上线只是开始。这篇讲三件事:备案合规收尾、日常运维、以及一整篇踩坑实录。
路径沿用第一篇的约定:/xxx 是占位符,请替换成你自己的部署目录。
一、备案与合规
1.1 公安联网备案
网站开通后 30 日内,到 beian.mps.gov.cn 做公安备案。注意:提交前确保网站能正常访问,审核人员会访问验证。
只需备案主域名,子域名不需要单独备案。
关键字段填写:
| 字段 | 填什么 |
|---|---|
| 网站名称 | 与 ICP 备案时一致 |
| 工信部备案号 | ICP 备案通过后获得的号码 |
| 主域名 | example.com(只填主域名) |
| IP | 服务器的公网 IP |
| 是否提供互联网交互服务 | 关评论 → 选「否」 |
| 网站性质 | 非经营性 |
| 网站级别 | 三级(无交互的个人主页) |
| 接入方式 | 租赁主机(云服务器属于租赁主机) |
「网络接入服务商」填买云服务器的商家,「域名注册服务商」填卖域名的商家。表单里一般有「查询网络接入商」按钮,点击可自动填入。常用云服务商信息如下:
| 云服务商 | 名称 | 电话 |
|---|---|---|
| 华为云 | 华为云计算技术有限公司 | 4000098660 |
| 阿里云 | 阿里云计算有限公司 | 4008013260 |
| 腾讯云 | 腾讯云计算(北京)有限责任公司 | 4009100100 |
1.2 备案号加到页脚
ICP 备案号和公安备案号都要展示。编辑主题的 footer.php,在 </body> 之前插入:
<div style="text-align:center;font-size:12px;color:#999;padding:16px 0;border-top:1px solid #eee;">
<a href="https://beian.miit.gov.cn/" target="_blank" rel="nofollow">湘ICP备XXXXXXXX号-1</a>
|
<a href="https://beian.mps.gov.cn/" target="_blank" rel="nofollow">湘公网安备XXXXXXXX号</a>
</div>公安备案通过前,可先写「公安联网备案中」,通过后再替换成真实备案号。
1.3 关评论 + 拦截评论接口
个人博客一般不需要评论,但「关评论」要两条腿一起做:
- 前端隐藏:Typecho 后台设置关闭评论,并注释掉主题里的评论框(
post.php/page.php中的comments.php引用); - 后端拦截:即使前端藏了评论框,评论 API 仍可被直接 POST 调用。在 Caddy 层彻底拦掉:
example.com {
@blockComment path /action/comment*
respond @blockComment 403
reverse_proxy typecho:80
}这样从入口就把评论接口堵死了,比只靠前端隐藏彻底得多。
二、博客定制与日常运维
2.1 主题定制备忘
换主题后要重做这几处(改的是主题文件,换主题就会失效):
- 评论框隐藏(
post.php/page.php); - 侧边栏「其它」仅登录后可见(
sidebar.php); - 隐藏「最近回复」(
sidebar.php); - 隐藏 RSS 和 Typecho 链接(
sidebar.php); - 页脚备案号(
footer.php)。
建议把这些改动沉淀成一份备忘文档,换主题时照做即可,不用每次重新回忆。
2.2 监控
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker stats --no-stream
free -h # 看 available 列
df -h2.3 更新镜像
cd /xxx/typecho
docker compose pull
docker compose down
docker compose up -d关键:pull 之后必须 down 再 up。只 pull && up -d 不会用新镜像重建容器(up -d 只检查配置变更),这是高频坑。
2.4 备份
创建备份脚本 /xxx/backups/backup.sh:
#!/bin/bash
BACKUP_DIR="/xxx/backups"
DATE=$(date +%Y%m%d)
RETENTION_DAYS=30
mkdir -p $BACKUP_DIR/$DATE
docker stop typecho
tar czf $BACKUP_DIR/$DATE/typecho.tar.gz -C /xxx/typecho html data
docker start typecho
# 删除超过 30 天的备份(排除备份根目录本身)
find $BACKUP_DIR -maxdepth 1 -type d -mtime +$RETENTION_DAYS ! -path "$BACKUP_DIR" -exec rm -rf {} \;
echo "Backup completed: $DATE"配置定时备份:
chmod +x /xxx/backups/backup.sh
crontab -e
# 每周日凌晨 3 点执行
0 3 * * 0 /xxx/backups/backup.sh避坑:find命令里的! -path "$BACKUP_DIR"是保命的。不加这个排除条件,一旦 30 天没备份,脚本会把整个/xxx/backups/目录删光。
2.5 安全加固
SSH 密钥登录——在本地电脑生成密钥对并上传:
ssh-keygen -t ed25519 -C "my-server"
ssh-copy-id root@你的服务器IP在服务器编辑 /etc/ssh/sshd_config:
PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin prohibit-password重启 SSH 服务:
systemctl restart ssh避坑:Ubuntu/Debian 的 SSH 服务名是ssh,不是sshd(CentOS 才是sshd)。另外改配置前务必先确认密钥登录能成功,否则可能把自己锁在服务器外。
端口收敛:上线验证通过后,注释掉 Typecho 的 9000 映射,最终只保留 22 / 80 / 443 三个端口。
三、问题集合
把整个过程中踩过的坑按类别汇总,每个坑都按「现象 → 根因 → 解法」记录,方便对照排查。
3.1 Typecho 镜像
| 现象 | 根因 | 解法 |
|---|---|---|
拉 joyqi/typecho 镜像返回 403,或容器起来后端口不明 | 第三方镜像在国内镜像站不稳定,内部端口不透明 | 改用 php:8.2-apache 官方镜像手动部署 |
3.2 部署类
| 现象 | 根因 | 解法 |
|---|---|---|
| Typecho 安装后所有链接指向 IP | 用 IP:9000 提前安装,网站地址被写进数据库 | 后台 → 设置 → 基本 → 网站地址改回 https://example.com;或一开始就用域名安装 |
3.3 Docker 类
| 现象 | 根因 | 解法 |
|---|---|---|
| 内存限制不生效 | deploy.resources 在非 Swarm 模式下静默失效 | 改用 mem_limit / mem_reservation |
| compose 启动有警告 | version: '3.8' 已废弃 | 删除该行 |
| 更新镜像后仍是旧版本 | pull && up -d 不会重建容器 | 加 down,即 pull && down && up -d |
docker pull 超时 | 未配置国内镜像加速 | 配置 /etc/docker/daemon.json 的 registry-mirrors |
3.4 Caddy · SSL 类
| 现象 | 根因 | 解法 |
|---|---|---|
| Caddyfile 不生效 | Linux 区分大小写,./Caddyfile 拼写不一致 | 核对卷挂载路径大小写 |
| Caddyfile 被空白配置覆盖 | 挂载了 ./config:/config,autosave 覆盖 | 不要挂载 config 目录 |
| 证书申请失败,浏览器一直显示「不安全」 | 80 端口未放行,或域名还没解析生效 | 放行 80 端口,确认 nslookup 返回正确 IP 后再访问 |
| 反向代理失败 | Caddyfile 里写了 localhost | 改用 Docker 容器名(如 typecho:80) |
3.5 系统类
| 现象 | 根因 | 解法 |
|---|---|---|
systemctl restart sshd 报错 | Ubuntu/Debian 服务名是 ssh 不是 sshd | 用 systemctl restart ssh |
3.6 备份类
| 现象 | 根因 | 解法 |
|---|---|---|
| 备份目录被整体删除 | find 未排除备份根目录 | 加 ! -path "$BACKUP_DIR" |
3.7 备案类
| 现象 | 根因 | 解法 |
|---|---|---|
| 公安备案审核不通过 | 网站无法访问 / 主域名无 A 记录 / 信息填错 | 确保 Caddy 和 Typecho 运行中,主域名有 A 记录,对照字段表检查 |
附:最终端口清单与目录结构
上线后的最终入站端口:
| 端口 | 用途 | 是否必需 |
| :-: | ----------------- | :--: |
| 22 | SSH 管理 | 必须 |
| 80 | Caddy HTTP(证书续期) | 必须 |
| 443 | Caddy HTTPS(用户访问) | 必须 |
目录结构:
/xxx/
├── caddy/
│ ├── Caddyfile
│ ├── docker-compose.yml
│ └── data/
├── typecho/
│ ├── docker-compose.yml
│ ├── html/
│ └── data/
└── backups/
└── backup.sh
暂无评论