重装系统与typecho迁移
前言
我写博客真可谓三天打鱼,两天晒网。大概两个月没维护,服务器被挖矿病毒感染,2核2g服务器有什么利用价值呢?不知道我的ssh密码怎么泄露了。检查了一下最终决定重装系统,同时加强了安全防护,设置了SSH不允许密码登录,防火墙开启(我一直觉得阿里云安全组的作用和防火墙一样,之前没设置).
重装系统前我备份了typecho数据库和图片。之前typecho安装是手动安装,这次我用docker镜像拉取,主要是想了解docker使用,结果是我这个docker小白拉镜像比手动安装还耗时间。QWEN给我写了docker配置文件,但是docker镜像太难找了,而且阿里的官方docker镜像里没有typecho(阿里云的docker镜像只能用在阿里云的服务器上,镜像地址要自己申请)。 最后在渡渡鸟镜像同步站搜到了typecho,才成功拉取镜像。
导入备份数据库后,打开安装引导网页,安装引导的最后选择保存数据。一切顺利,但安装完成跳转到博客网站时显示server error,我重装了几次都是这样,最后查typecho日志显示问题时插件缺失。因为我之前安装并启用了一个目录插件,数据库里保存了这个插件,导入备份数据后,typecho以为有这个插件,想要运行,但是没有插件,所以报错。让AI写SQL把插件全设为不启用后就可以正常显示了。
我重装了好几次,配置文件config.inc.php也搞了好几次,我的经验是备份的时候可以把配置文件也备份一下,这样导入数据后就不用再重复安装引导了。或者整个typecho目录都做备份,直接导入,配置好数据库。
数据库迁移整个过程比较简单,这次迁移系统我顺便加了图床,用的也是博客里常用的免费方案CloudFare R2和PicGo。
重装系统,设置
重装系统时选择了ubuntu22,不禁感慨时间流逝,大二学计算机系统和操作系统时,ubuntu22还是新系统,据说ubuntu20不稳定,我都会安装ubuntu20,如今ubuntu20已不再维护。
阿里云的服务器ubuntu系统apt初始就已经换了阿里源
python换源
# 清华源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
# 或阿里云源
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip config list docker 换源
echo ">>> 配置 Docker 镜像加速器..."
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null << EOF
{"registry-mirrors": ["https://docker.1ms.run"]}
EOF
sudo systemctl restart docker 2>/dev/null && echo "✓ Docker 源配置完成" || echo "⚠️ Docker 未安装或未运行"
创建用户
sudo adduser hhh
# 将用户加入 sudo 组(Ubuntu 默认配置)
sudo usermod -aG sudo hhh
# 验证
groups hhh # 应包含 "sudo"
sudo usermod -aG docker hhh
# 重新加载组权限(当前会话立即生效)
newgrp docker # 或直接退出重新登录 SSH
# 验证
su - hhh
docker ps # 新建用户创建密钥
# 本地终端执行(不要在服务器上!)
ssh-keygen -t ed25519 -C "hh@ali-ecs" -f ~/.ssh/id_ed25519_hh
# 按提示:
# 1. Enter passphrase(可选但推荐,增加安全性)
# 2. 确认 passphrasedocker 安装typecho
拉取并构建镜像
typecho镜像只包括typecho的前后端,还需要加入数据库镜像。nginx我也想加入镜像的,这样就可以一键重装了,但是网络有点麻烦。
services:
typecho:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/joyqi/typecho:nightly-php8.2-apache # 镜像地址
container_name: typecho-server # 容器名
restart: always
environment:
- TYPECHO_SITE_URL=https://strangeloop.fun
- TZ=Asia/Shanghai
ports:
- 8080:80 # 端口映射
volumes:
- /var/typecho:/app/usr # 同步数据
- /etc/localtime:/etc/localtime:ro # 同步时间
- /var/blog_backup/assets:/app/assets # 图片
depends_on:
- db
db:
image: postgres:14-alpine
container_name: typecho-db
restart: always
environment:
- POSTGRES_USER=typecho
- POSTGRES_PASSWORD=my_password
- POSTGRES_DB=typecho
volumes:
- /var/pg_data:/var/lib/postgresql/data
- /etc/localtime:/etc/localtime:ro
docker compose up -d导入数据并进行配置
打开http://47.116.68.4:8080 不能打开,因为8080端口未配置安全组规则
我先导入了备份数据,显示数据库已存在,可能是数据库选错了,重新配置,或者修改配置文件。
docker exec typecho-db pg_restore -U typecho -d typecho --no-owner --no-acl /tmp/backup.dump # 导入备份数据库
# 下面是我安装后出现server error后删掉数据库重新开始的指令,跳过
docker exec typecho-db psql -U typecho -d typecho -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"
docker exec typecho-db psql -U typecho -d typecho -c "\dt"
docker exec typecho-server cat /app/config.inc.php | sudo tee /var/typecho/config.inc.php > /dev/null初始化逻辑:Typecho 官方镜像在启动时,如果检测到 /app/config.inc.php 不存在,就会触发安装引导。
server error原因是插件缺失,可以把原插件复制过去,也可以直接修改数据库。所以usr文件夹应该全保存下来的,主题也在usr下面。
# 禁用所有插件(正确的格式)
docker exec typecho-db psql -U typecho -d typecho -c "UPDATE typecho_options SET value = 'a:2:{s:9:\"activated\";a:0:{}s:7:\"handles\";a:0:{}}' WHERE name = 'plugins';"
# 验证
docker exec typecho-db psql -U typecho -d typecho -c "SELECT value FROM typecho_options WHERE name = 'plugins';"之后 ip可以访问博客,但是域名不能访问,并且排版混乱
排版混乱是因为浏览器阻止了 HTTP 的 CSS/JS 资源(混合内容)
申请证书后,你将 Typecho 的站点地址改为https://,所有资源链接变成 HTTPS,浏览器允许加载 → 排版恢复正常 ✅
521 错误表示 Cloudflare 能连到你的服务器,但服务器 80/443 端口没有响应。根本原因:
✅ IP:8080 能访问 → 说明 Typecho 容器正常运行
❌ 域名不能访问 → 说明服务器 80 端口没有服务(Cloudflare 默认访问 80/443 端口)
# 1. 安装 Nginx
sudo apt install -y nginx
# 2. 创建配置
sudo tee /etc/nginx/sites-available/strangeloop.fun <<'EOF'
server {
listen 80;
server_name strangeloop.fun www.strangeloop.fun;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
EOF
sudo ln -sf /etc/nginx/sites-available/strangeloop.fun /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default 2>/dev/null
# 3. 重载 Nginx
sudo nginx -t && sudo systemctl reload nginx
# 4. 开放防火墙
sudo ufw allow 80/tcp
# 5. 浏览器访问
http://strangeloop.fun # 应该正常显示博客!服务器安全设置
Fail2ban(必备!)
防止 SSH/WordPress/Typecho 登录暴力破解
# 安装
sudo apt update && sudo apt install -y fail2ban
# 配置(创建自定义配置)
sudo tee /etc/fail2ban/jail.local > /dev/null <<'EOF'
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3 # 3次失败即封禁
bantime = 86400 # 封禁24小时
findtime = 600 # 10分钟内累计失败
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
EOF
# 启动
sudo systemctl enable fail2ban && sudo systemctl restart fail2ban
# 验证
sudo fail2ban-client status sshd
# 输出示例:Currently banned: 2(已封禁2个IP)# 2. 配置 SSH 密钥登录(本地电脑执行):
# ssh-keygen -t ed25519
# ssh-copy-id root@ip
# 3. 禁用密码登录(服务器执行)
echo "PasswordAuthentication no" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshdufw 配置及修改SSH端口
我还修改了ssh端口,一朝被蛇咬...
ssh端口加入新端口后测试新端口可用再删除旧端口,否则后果不堪设想,又要重装了。
ufw启用的时候注意先添加规则,不然后果也不堪设想。

# 1. 允许当前 SSH 端口(22)
sudo ufw allow 22/tcp comment 'SSH access'
# 2. 允许 Web 服务
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
# 3. (可选)仅允许您的 IP 访问 SSH(更安全)
# sudo ufw delete allow 22/tcp # 先删除全局规则
# sudo ufw allow from YOUR_IP to any port 22 proto tcp comment 'SSH from home'
# 4. 查看规则预览(确认无误再启用)
sudo ufw status verbose# 1. 添加您的 IP 规则(假设 IP=123.123.123.123)
sudo ufw allow from 123.123.123.123 to any port 22 proto tcp
# 2. 删除全局 22 规则(编号1)
sudo ufw delete 1
# 3. 验证结果
$ sudo ufw status numberedgithub ssh密钥设置
ssh连接下载代码快很多。
ssh-keygen -t ed25519 -C "szh-nine@outlook.com"
# 把公钥添加到github
ssh -T git@github.com # 连接
git config --global user.email "szh-nine@outlook.com"
git config --global user.name "Zihui Si"
git remote add origin git@github.com:amorfatix/blog.git
git push -f -u origin master # 强制推送(覆盖远程)Cloudfare R2 + PicGo 替换图片上传
本地博客自动发布之钻木取火我这篇博客记录我之前上传图片和博客的方法,非常原始。当时我觉得这样很好。
但现在这样迁移到docker环境那些图片更麻烦,为了配合之前博客里的路径,我直接把图片文件夹共享到了docker里的/app/assets,这一点在前面的配置文件里可以看到。
我选择拥抱图床,有了图床博客发布的问题的问题也解决了。
在诸多图床服务里我选择了Cloudfare R2 + PicGo,R2免费提供10G存储空间,每月访问1M次数,用于我的博客是绰绰有余。PicGo是一个便捷的图片上传工具,它对Typora的适配也比较好。
R2需要验证信用卡信息或者paypal,普通借记卡也可以添加到paypal作为验证,我用paypal过了信息验证。
后续教程参考:
跟着教程和AI走,还是有一些需要自己摸索的地方:
自定义输出URL
我在cloudfare R2里设置了自定义的域名
img.strangeloop.fun我按照信息配置好之后上传图片返回的路径却是<img src="https://blog-image.366cd17fc303b00c17d2ee37b9cdf8fa.r2.cloudflarestorage.com/20260213224039332.png"/>需要自定义输出url模板如下:

配置安全规则防盗链
- 如果 Referer 不包含
strangeloop.fun - 并且 host 是
img.strangeloop.fun - 并且 Referer 不为空
- → 阻止
(not http.referer contains "strangeloop.fun" and http.host eq "img.strangeloop.fun" and http.referer ne "")- 如果 Referer 不包含
PicGo使用
Typora里添加PicGo的路径后设置后可以自动上传,但是不是所有写作场景都需要自动上传图片——草稿、临时笔记、本地文档没必要占用 R2 空间。
PicGo 独立使用(最通用,推荐⭐⭐⭐⭐⭐)
核心思想:不依赖编辑器集成,用 快捷键/拖拽 主动上传,完全掌控何时上传。
设置 PicGo 快捷键
- PicGo → 设置 → 快捷键上传
推荐:
Ctrl+Shift+U(Windows)/Cmd+Shift+U(Mac)
- 工作流
1. 截图 → 自动保存到剪贴板 2. 按快捷键 Ctrl+Shift+U → PicGo 自动上传 3. 链接自动复制到剪贴板 4. 在任意编辑器(Typora/VS Code/Obsidian/Notion)中 Ctrl+V 粘贴链接使用体验:截图后使用快捷键上传很方便,上传时间大概几秒,略慢,不要重复上传。
我现在改用了图床,之前的照片也要上传上去,上传之后博客里的路径替换
旧路径: https://strangeloop.fun/assets/image-20250706145859046.png 新路径: https://img.strangeloop.fun/image-20250706145859046.png ↓ https://strangeloop.fun/assets/ → https://img.strangeloop.fun/- 备份数据库
- 路径批量替换
刷新网站,照片能够显示,完成
docker exec typecho-db pg_dump -U typecho -d typecho > backup_$(date +%Y%m%d).sql # 连接数据库 # 进入容器并启动 psql docker exec -it typecho-db psql -U typecho -d typecho # 然后在 psql 中执行: UPDATE typecho_contents SET text = REPLACE( text, 'https://strangeloop.fun/assets/', 'https://img.strangeloop.fun/' ) WHERE type IN ('post', 'page'); -- 验证 SELECT COUNT(*) as updated_count FROM typecho_contents WHERE text LIKE '%https://img.strangeloop.fun/%' AND type IN ('post', 'page'); -- 检查是否还有旧路径 SELECT cid, title FROM typecho_contents WHERE text LIKE '%https://strangeloop.fun/assets/%'; -- 退出 psql \q



