PacketForge 博客部署文档

PacketForge 博客部署文档

PacketForge
2026-08-14 / 1 评论 / 8 阅读 /
版本: v1.0 | 2026-08-14
适用环境: 阿里云 ECS / Ubuntu 24.04 LTS / 2C2G
本文档已去敏: 所有 IP、密码、密钥路径均为占位符

一、架构总览

公网:8899 → Nginx
              ├── /            → Typecho (PHP-FPM 8.3)
              ├── /admin/      → Typecho 后台
              └── /usr/uploads → 附件目录 (浏览器缓存30天)

数据层: SQLite 单文件数据库 (/opt/typecho/usr/*.db)
主题:   Joe (已打 SQLite/PHP8.3 兼容补丁)
服务:   Nginx + PHP-FPM (systemd 托管, 开机自启)

环境要求:

版本
OSUbuntu 24.04 LTS
WebNginx 1.24+
PHP8.3 (FPM)
数据库SQLite3 (免 MySQL)
内存2G 足够 (实际占用 ~500M)

二、部署步骤

第 1 步: 服务器基础

apt update && apt install -y nginx php8.3-fpm \
  php8.3-sqlite3 php8.3-mbstring php8.3-curl php8.3-gd php8.3-xml

第 2 步: 上传 Typecho

# 本地下载 (Typecho 官方 GitHub master 分支)
# 解压后整体上传到 /opt/typecho/
# 目录权限:
chown -R www-data:www-data /opt/typecho
chmod -R 755 /opt/typecho

第 3 步: Nginx 配置

server {
    listen 8899;                    # 非标准端口, 降低扫描风险
    server_name 服务器IP;
    server_tokens off;
    client_max_body_size 50m;

    root /opt/typecho;
    index index.php index.html;

    # gzip 压缩
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_comp_level 6;
    gzip_types text/css text/javascript application/javascript application/json image/svg+xml;

    # 安全响应头
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;

    # 静态资源缓存 (7天)
    location ~* \.(css|js|png|jpg|jpeg|gif|webp|svg|ico|woff|woff2|ttf)$ {
        expires 7d;
        add_header Cache-Control "public, max-age=604800";
        try_files $uri $uri/ /index.php?$query_string;
    }

    # 上传文件缓存 (30天)
    location /usr/uploads/ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }

    # 禁止访问数据库等敏感文件
    location ~* \.(db|sqlite|sqlite3)$ { deny all; }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* { deny all; }
}

登录限速 (防暴力破解, 加在 nginx.conf 的 http 块):

limit_req_zone $binary_remote_addr zone=login_limit:10m rate=30r/m;
# sites-available 里加:
location = /action/login {
    limit_req zone=login_limit burst=5 nodelay;
    try_files $uri $uri/ /index.php?$query_string;
}

第 4 步: 浏览器安装

访问 http://服务器IP:8899/install.php
→ 数据库适配器选 SQLite
→ 设置管理员账号密码 (自定义)
→ 安装完成后删除 install.php 和 install/ 目录

第 5 步: 安全加固 (必做)

# 1. 删除安装文件
rm -f /opt/typecho/install.php
rm -rf /opt/typecho/install

# 2. 数据库文件禁止 web 访问 (已含在 Nginx 配置)

# 3. 后台设置:
#    - 设置 → 评论 → 开启评论审核
#    - 密码设 12 位以上混合字符

第 6 步: 阿里云安全组

方向端口说明
入方向22SSH (仅密钥登录)
入方向8899博客访问
其他全部拒绝

三、Joe 主题部署与补丁

主题安装

# Joe 主题上传到 /opt/typecho/usr/themes/joe/
chown -R www-data:www-data /opt/typecho/usr/themes/joe
# 后台 → 外观 → 启用 Joe → 设置外观 → 保存一次(初始化配置)

必打补丁 (Joe 与 Typecho 1.3 + SQLite 兼容)

Joe 原作者已停更,不原生兼容 Typecho 1.3+/SQLite,需打三个补丁:

补丁 1: SQLite 注册 MySQL 兼容函数

文件: var/Typecho/Db/Adapter/Pdo/SQLite.phpinit() 方法中,PDO 创建后注册:

// RAND() → 0~1 随机数
$pdo->sqliteCreateFunction('RAND', function () {
    return mt_rand() / mt_getrandmax();
}, 0);
// FROM_UNIXTIME(ts, fmt)
$pdo->sqliteCreateFunction('FROM_UNIXTIME', function ($ts, $fmt = '%Y-%m-%d %H:%i:%s') {
    $phpFmt = str_replace(
        ['%Y', '%y', '%m', '%c', '%d', '%e', '%H', '%k', '%i', '%s', '%M', '%j'],
        ['Y', 'y', 'm', 'n', 'd', 'j', 'H', 'G', 'i', 's', 'F', 'z'],
        (string) $fmt
    );
    return date($phpFmt, intval($ts));
}, 2);
// UNIX_TIMESTAMP()
$pdo->sqliteCreateFunction('UNIX_TIMESTAMP', function ($v = null) {
    return $v === null ? time() : strtotime((string) $v);
}, 1);
// DATE_FORMAT(date, fmt)
$pdo->sqliteCreateFunction('DATE_FORMAT', function ($date, $fmt) {
    $phpFmt = str_replace(
        ['%Y', '%y', '%m', '%c', '%d', '%e', '%H', '%k', '%i', '%s'],
        ['Y', 'y', 'm', 'n', 'd', 'j', 'H', 'G', 'i', 's'],
        (string) $fmt
    );
    $ts = is_numeric($date) ? intval($date) : strtotime((string) $date);
    return $ts ? date($phpFmt, $ts) : null;
}, 2);

补丁 2: 随机文章 RAND() 改 PHP 实现

文件: usr/themes/joe/core/function.php_getAsideAuthorNav(),SQL 里的 RAND() 改为:

$minMax = $db->fetchRow("SELECT MIN(cid) AS minCid, MAX(cid) AS maxCid FROM `{$prefix}contents` WHERE type='post' AND status='publish'");
$randomCid = ($minMax && $minMax['maxCid']) ? mt_rand(intval($minMax['minCid']), intval($minMax['maxCid'])) : 0;
$sql = "SELECT * FROM `{$prefix}contents` WHERE cid >= {$randomCid} and type='post' and status='publish' and (password is NULL or password='') ORDER BY cid LIMIT $limit";

补丁 3: 建站日期必须带时分秒

Joe 的运行时间计数器正则要求格式 YYYY/M/D HH:MM:SS

  • 后台 Joe 设置 → 建站日期 → 必须填 2026/8/13 17:30:00 格式(带时间),否则计数器显示 00

品牌自定义

位置修改
后台 → 设置 → 基本 → generatorPacketForge 1.3.0(保留版本号,改名前半部分即可,去掉版本号会导致后台 500)
后台登录页 Logoadmin/login.php 中 h1 链接改为自己品牌
Joe 页脚外观设置 → JFooter_Left / JFooter_Right

四、运维手册

日常操作

操作命令/位置
写文章后台 /admin/ 撰写
备份数据库复制 /opt/typecho/usr/*.db 文件即可(SQLite 单文件)
备份 Joe 配置复制 typecho_optionstheme:joe 记录
查看日志tail -f /var/log/nginx/error.log

备份脚本

#!/bin/bash
# 备份 SQLite 数据库 + Joe 配置
BK=/opt/backups/$(date +%Y%m%d)
mkdir -p $BK
cp /opt/typecho/usr/*.db $BK/
php8.3 -r '$db = new SQLite3("/opt/typecho/usr/数据库名.db");
  $v = $db->querySingle("SELECT value FROM typecho_options WHERE name=\"theme:joe\"");
  file_put_contents("'$BK'/joe-config.json", json_encode(json_decode($v), JSON_PRETTY_PRINT));'

故障恢复

故障处理
前台 500/var/log/nginx/error.log 的 PHP message;常见原因是主题配置被清空 → 恢复 joe-config 备份
后台 500检查 generator 字段格式是否为 "名字 版本号"(两个词)
主题切换后 Joe 配置丢失Typecho 切换主题会清空旧主题配置——切之前先备份 theme:joe 记录
运行时间计数器 00建站日期没带时分秒,补成 YYYY/M/D HH:MM:SS

已知注意事项

  1. 不要把 generator 字段改成无版本号格式(如纯 "PacketForge"),Typecho 内部解析版本会崩溃
  2. 不要在后台切换主题前不备份——Joe 配置会被清空
  3. Typecho 升级时 Pdo/SQLite.php 适配器补丁可能被覆盖,升级后需重新打补丁 1
  4. 上传限制: PHP-FPM 的 upload_max_filesize=20M, post_max_size=32M

五、安全基线

状态
数据库文件 web 访问✅ deny all
install.php✅ 已删除
登录限速✅ 30r/m + burst 5
安全响应头✅ 4 项
版本号泄露✅ server_tokens off
开放注册✅ 关闭
XML-RPC✅ 仅登录用户
附件类型✅ 仅图片
SSH✅ 仅密钥
安全组✅ 仅 22 + 8899

去敏说明: 本文档中服务器 IP、管理员密码、数据库文件名、密钥路径均已用占位符替代。实际部署时替换为真实值。
1

评论 (1)

取消
  1. 头像
    PacketForge 作者
    2026-08-14 10:33 · 60.12.136.126 · 浙江 杭州 联通 · Windows 10/11 · Edge 150.0.0.0 · 电脑
    @

    nice

    回复