撰于 阅读 50

搭建typecho博客

搭建typecho博客

上班摸鱼的时候,刷到了网友的博客。觉得建设的很好,想起来之前自己也搭过基于wordpress的博客,但是因为wordpress太重而且用起来体验也很不好就放弃了。心血来潮又研究了一下typecho这个博客平台。发现比较简洁,同时还支持好用的Markdown语法,于是决定搭一个试试看。

服务器搭建

参考了官方的repo,编写了如下的docker-compose.yaml

version: '3.7'

services:
  typecho:
    image: joyqi/typecho:nightly-php8.2-apache
    container_name: typecho-server
    restart: always
    environment:
      - TYPECHO_SITE_URL=https://wp.mqlhaha.cn
      - TIMEZONE=Asia/Shanghai
      - TYPECHO_DB_ADAPTER=Pdo_Pgsql
      - TYPECHO_DB_HOST=xxxx
      - TYPECHO_DB_PORT=xxxx
      - TYPECHO_DB_USER=xxxx
      - TYPECHO_DB_PASSWORD=xxx
      - TYPECHO_USER_NAME=xxx
      - TYPECHO_USER_PASSWORD=xxxx
      - TYPECHO_USER_MAIL=xxxx
    ports:
      - 8080:80
    volumes:
      - ./typecho_data:/app/usr

执行docker compose up -d后,服务成功启动。

问题排查

打开页面执行安装,此时发现了参照官方repo填写的环境变量并没有生效,并且重启服务后需要重新安装。

经过搜索后,发现了有相关的issue。原来的docker-compose.yaml文件存在问题,包括

  1. 没有设置TYPECHO_INSTALL环境变量,默认为0,即不执行自动安装
  2. 没有设置TYPECHO_DB_NEXT环境变量,默认为none,此时即使读取到数据库的信息,也不执行任何操作,故仍会在启动后出现安装界面
  3. 卷映射中需要添加对/app这个目录的映射,否则重启后仍然需要重新安装(原因是config.inc.php文件没有持久化存储,其中包含了一些服务器的配置文件)

修复上述问题后的docker-compose.yaml文件如下:

version: '3.7'

services:
  typecho:
    image: joyqi/typecho:nightly-php8.2-apache
    container_name: typecho-server
    restart: always
    environment:
      - TYPECHO_SITE_URL=https://wp.mqlhaha.cn
      - TYPECHO_INSTALL=1
      - TIMEZONE=Asia/Shanghai
      - TYPECHO_DB_ADAPTER=Pdo_Pgsql
      - TYPECHO_DB_HOST=xxx
      - TYPECHO_DB_PORT=xxx
      - TYPECHO_DB_USER=xxx
      - TYPECHO_DB_PASSWORD=xxx
      - TYPECHO_USER_NAME=xxx
      - TYPECHO_USER_PASSWORD=xxx
      - TYPECHO_USER_MAIL=xxx
      - TYPECHO_DB_NEXT=keep
    ports:
      - 8080:80
    volumes:
      - ./typecho_data:/app/usr
      - ./typecho_installer:/app

此时typecho服务正常了,重启后也能正常访问。计划登录后台执行一些初始化,发现在PC端无法正常登录管理后台,但是在手机端开启wireguard VPN后可以正常访问。结合网络设置,发现是部分请求自动使用了http协议导致。参照此issue,在config.inc.php文件中添加如下命令

define('__TYPECHO_SECURE__', true);

再次访问typecho网站,发现正常了

进阶配置

迁移至Mysql

尝试设置自定义主题山海,下载并启用后有报错,发现和数据库相关。同样的尝试安装访客插件也报错。经排查发现是PGSQL数据库的问题。由于国内mysql非常流行,推测是大部分插件和主题开发的时候并没有直接用typecho提供的数据库插件,而是直接绑定了mysql的语法。因此参照文档搭建了如下的mysql服务器以供后续其他服务使用

version: '3.1'

services:

  db:
    image: mysql
    restart: always
    ports:
      - 3306:3306
    volumes:
      - ./mysqldata:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: xxxxxxxxx

启动mysql,重新以mysql作为数据库后端安装typecho后,自定义主题和插件都正常了

CDN优化

加入了阿里云CDN以进行外网访问优化。开通CDN后,需要在域名解析处将原先的A记录暂停解析,转而修改为指向阿里云CDN域名的CNAME记录。

此外,还需要加入如下规则:

目录/文件名缓存时间权重说明
jpg,png,jpeg,txt1 月52缓存图片
/admin/051确保管理界面正常使用
/1小时50默认策略,避免文章长时间不更新

自定义主题优化

本博客基于山海主题。发布了第一篇blog,我发现首页加载会非常慢。

查看加载过程,发现在首页上的Post会使用文章内的图片作为logo。而我上传的图片可能会比较大(>10M),这就导致了首页比较慢。使用F12工具,基于HTML标签定位,定位到在functions.php中有如下函数

function analyzePostContent($content)
{
    // 包含图片
    if (strpos($content, '<img') !== false) {
        preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches);
        return '<img class="w-[20px] h-[20px] inline-block rounded" src="' . $matches[1][0] . '" />';
    }
    // 包含代码
    if (strpos($content, '<code') !== false || strpos($content, '<pre') !== false) {
        return '<svg height="1.5em" width="1.5em" class="inline-block" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24"  xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M9.4 16.6 4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0 4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></svg>';
    }

    return '<svg height="1.5em" width="1.5em" class="inline-block" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M2.5 4v3h5v12h3V7h5V4h-13zm19 5h-9v3h3v7h3v-7h3V9z"></path></svg>';
}

此函数会检测文章内是否有图片。如有,则会返回图片,否则返回SVG小图标。因此修改此函数逻辑为有图片时也返回SVG小图标即可。在网上找了一个SVG图标加入:

function analyzePostContent($content)
{
    // 包含图片
    if (strpos($content, '<img') !== false) {
        //preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches);
        //return '<img class="w-[20px] h-[20px] inline-block rounded" src="' . $matches[1][0] . '" />';
        return '<svg height="1.5em" width="1.5em" class="inline-block" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24"  xmlns="http://www.w3.org/2000/svg"><path d="M18.555,15.354V4.592c0-0.248-0.202-0.451-0.45-0.451H1.888c-0.248,0-0.451,0.203-0.451,0.451v10.808c0,0.559,0.751,0.451,0.451,0.451h16.217h0.005C18.793,15.851,18.478,14.814,18.555,15.354 M2.8,14.949l4.944-6.464l4.144,5.419c0.003,0.003,0.003,0.003,0.003,0.005l0.797,1.04H2.8z M13.822,14.949l-1.006-1.317l1.689-2.218l2.688,3.535H13.822z M17.654,14.064l-2.791-3.666c-0.181-0.237-0.535-0.237-0.716,0l-1.899,2.493l-4.146-5.42c-0.18-0.237-0.536-0.237-0.716,0l-5.047,6.598V5.042h15.316V14.064z M12.474,6.393c-0.869,0-1.577,0.707-1.577,1.576s0.708,1.576,1.577,1.576s1.577-0.707,1.577-1.576S13.343,6.393,12.474,6.393 M12.474,8.645c-0.371,0-0.676-0.304-0.676-0.676s0.305-0.676,0.676-0.676c0.372,0,0.676,0.304,0.676,0.676S12.846,8.645,12.474,8.645"></path></svg>';
    }
    // 包含代码
    if (strpos($content, '<code') !== false || strpos($content, '<pre') !== false) {
        return '<svg height="1.5em" width="1.5em" class="inline-block" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24"  xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0V0z"></path><path d="M9.4 16.6 4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0 4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"></path></svg>';
    }

    return '<svg height="1.5em" width="1.5em" class="inline-block" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill="none" d="M0 0h24v24H0z"></path><path d="M2.5 4v3h5v12h3V7h5V4h-13zm19 5h-9v3h3v7h3v-7h3V9z"></path></svg>';
}

完成后首页加载速度快了很多。

上传优化

由于会有摄影相关的文章,默认的10M上传大小肯定是不够用的,需要修改。typecho是基于php进行开发的,而我部署的是Docker容器化版本,在每次启动时都会修改默认的php参数。

查询源码,发现有如下定义:

ENV MEMORY_LIMIT=128m
ENV MAX_POST_BODY=10m
ENV MAX_EXECUTION_TIME=30

因此只需要在docker-compose.yaml文件中覆写这里定义的环境变量即可调整上传相关的参数。