Files
trojanZ/迁移实施记录-2026-07-26.md
2026-07-26 17:20:23 +08:00

11 KiB
Raw Permalink Blame History

Trojan、Nginx、Caddy 与 Gitea 迁移实施记录

实施日期:2026-07-26

1. 服务器与域名

服务器 Trojan 与管理后台 Gitea 宿主机 SSH Git SSH
43.154.35.111 www.hk.chermack.top git.hk.chermack.top 22 2222
43.159.139.193 www.us.chermack.top git.us.chermack.top 22 2222

2. 最终架构

flowchart LR
  U[客户端] -->|HTTP :80| N[Nginx]
  U -->|HTTPS :443 / SNI| N
  N -->|www.* HTTP| W[Trojan 管理后台 :8081]
  N -->|www.* TLS 透传| T[Trojan :8443]
  T -->|非 Trojan 流量回落| W
  N -->|git.* HTTP| C1[Caddy :8080]
  N -->|git.* TLS 透传| C2[Caddy :9443]
  C1 --> G[Gitea :3000]
  C2 --> G
  U -->|Git SSH :2222| G

公网 80/443 只由宿主机 Nginx 监听。Trojan 客户端和 Trojan 管理后台继续共用 www.* 域名,不新增 panel 域名:Nginx 将 www.* 的 TLS 按 SNI 透传到 TrojanTrojan 对非 Trojan TLS 流量回落到本机管理后台。

3. 迁移前备份与检查

在变更前检查原容器和配置:

docker ps
docker inspect trojan
docker exec trojan cat /usr/local/etc/trojan/config.json
docker exec trojan systemctl cat trojan-web.service

已创建的备份目录:

/root/trojan-gitea-migration-backup-20260726-004630  # 香港
/root/trojan-gitea-migration-backup-20260726-014435  # 美国
/root/gitea-pre-reset-20260726-012207                # 香港 Gitea 重置前

香港服务器另保留了迁移前 Trojan 镜像快照。

4. Trojan 端口调整

容器内 Trojan 配置调整为:

{
  "local_port": 8443,
  "remote_port": 8081
}

管理后台 systemd unit 调整为:

ExecStart=/usr/local/bin/trojan web --host 127.0.0.1 --port 8081

重载和启动命令:

docker exec trojan systemctl daemon-reload
docker exec trojan systemctl enable trojan-web
docker exec trojan systemctl restart trojan
docker exec trojan systemctl restart trojan-web

预期监听:Trojan 为 0.0.0.0:8443,管理后台为 127.0.0.1:8081。这两个端口不应对公网开放。

5. Nginx 统一入口

安装并启用:

apt-get update
apt-get install -y nginx libnginx-mod-stream
systemctl enable --now nginx
nginx -t

443 使用 streamssl_preread 按 SNI 分流。香港示例(美国替换为 www.us.chermack.topgit.us.chermack.top):

map $ssl_preread_server_name $tls_backend {
    www.hk.chermack.top  127.0.0.1:8443;
    git.hk.chermack.top  127.0.0.1:9443;
    default              127.0.0.1:8443;
}
server {
    listen 443;
    proxy_pass $tls_backend;
    ssl_preread on;
}

80 的 www.* 虚拟主机反向代理到 127.0.0.1:8081,并将 /.well-known/acme-challenge/ 转发到 127.0.0.1:8082git.* 反向代理到 Caddy 127.0.0.1:8080

每次配置改动后:

nginx -t && systemctl reload nginx

6. Gitea 与 Caddy

/opt/gitea 使用 Docker Compose 运行:

  • Gitea 1.27.0127.0.0.1:3000->30002222->22
  • PostgreSQL 16:仅 Docker 内网;
  • Caddy127.0.0.1:8080->80127.0.0.1:9443->443,反向代理到 Gitea。
cd /opt/gitea
docker compose up -d
docker compose ps

Caddy 管理 git.* 的 HTTPS 证书和自动续期;Nginx 对 Git 的 443 流量仅做 TLS 透传。Gitea 初始化时应填写:

ROOT_URL: https://git.<地区>.chermack.top/
SSH 域名: git.<地区>.chermack.top
SSH 端口: 2222

香港 Gitea 曾按授权清空数据并重新初始化;再次重置前必须先备份 /opt/gitea/gitea/opt/gitea/postgres

7. 美国服务器 SSH 端口处理

美国服务器原 OpenSSH 监听 2222222223,与 Gitea Git SSH 的 2222 冲突。已保留宿主机 SSH 22,移除宿主机的 2222/2223 监听,并将 2222 留给 Gitea。

变更前备份:

/etc/ssh/sshd_config.pre-gitea-20260726-014417

安全操作:

sshd -t
systemctl reload ssh
ss -ltnp | grep sshd

修改 SSH 配置时必须保持一条现有的 22 端口会话,验证完成后再断开。

8. Trojan 证书续期

Trojan 的 www.* 证书仍由容器内 acme.sh 管理;Caddy 只管理 git.*。由于宿主机 80 已交给 NginxTrojan standalone 验证改用本地 8082

docker exec trojan /root/.acme.sh/acme.sh --issue \
  --server letsencrypt --standalone --httpport 8082 \
  -d www.hk.chermack.top --ecc --force
docker exec trojan systemctl restart trojan

美国服务器替换为 www.us.chermack.top。本次两张 Trojan 证书均已成功签发,有效期为 2026-07-25 至 2026-10-23。后续应确认容器内自动续期任务也携带 --httpport 8082

9. 重启后不可用:原因与永久修复

现象

香港服务器重启后,Nginx、Trojan 容器、Gitea、Caddy 都自动启动,但:

docker exec trojan systemctl is-active trojan       # inactive
docker exec trojan systemctl is-active trojan-web   # inactive

此时没有 84438081 监听,因此 www.hk.chermack.top 不可用。

临时恢复

docker exec trojan systemctl start trojan
docker exec trojan systemctl start trojan-web
ss -ltnp | grep -E ':(8443|8081)'

永久兜底

容器内 unit 虽为 enabled,但容器启动时没有拉起服务。因此在香港宿主机新增并启用:/etc/systemd/system/trojan-container-services.service

[Unit]
Description=Start Trojan services inside the trojan container
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/docker exec trojan /bin/systemctl start trojan.service
ExecStartPost=/usr/bin/docker exec trojan /bin/systemctl start trojan-web.service
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

启用并验证:

systemctl daemon-reload
systemctl enable trojan-container-services.service
systemctl start trojan-container-services.service
systemctl is-enabled trojan-container-services.service
systemctl is-active trojan-container-services.service
docker exec trojan systemctl is-active trojan trojan-web

本次已验证该兜底服务为 enabledactiveTrojan 和 trojan-web 均为 active,且外部 HTTPS 访问 https://www.hk.chermack.top/ 成功。

美国服务器也已部署同名的宿主机兜底 unit,并完成验证:trojan-container-services.serviceenabledactiveTrojan 监听 0.0.0.0:8443,管理后台监听 127.0.0.1:8081https://www.us.chermack.top/https://git.us.chermack.top/ 外部访问均成功。

10. 日常检查与故障排查

# 统一入口、监听与容器
nginx -t
ss -ltnp | grep -E ':(80|443|8080|8081|8443|9443|2222)'
docker ps

# Trojan 及后台
docker exec trojan systemctl is-active trojan
docker exec trojan systemctl is-active trojan-web

# Web 链路
curl -kI https://www.hk.chermack.top/
curl -kI https://git.hk.chermack.top/
curl -kI https://www.us.chermack.top/
curl -kI https://git.us.chermack.top/

www.* 不可访问时,先检查 trojan-web8081;Trojan 客户端也异常时,再检查 trojan8443

docker exec trojan systemctl restart trojan
docker exec trojan systemctl restart trojan-web
docker exec trojan journalctl -u trojan -u trojan-web --no-pager -n 200
docker logs --tail 200 trojan

11. 美国服务器 Gitea 初始化记录

初始化页面曾提示数据库密码无效。服务器内核验结果如下:

  • gitea 容器的 GITEA__database__*gitea-db 容器的 POSTGRES_* 用户、数据库和密码完全一致;
  • 使用 Gitea 容器实际注入的密码连接 PostgreSQL 成功;
  • /data/gitea/conf/app.ini 中落盘的密码也与 PostgreSQL 一致;
  • 初始化页面已预填密码,错误由浏览器密码管理器覆盖表单密码或提交了其他密码造成,不是数据库密码失效。

为避免表单再次覆盖,已通过 Gitea CLI 使用明确配置文件完成初始化:

gitea --work-path /data/gitea \
  --config /data/gitea/conf/app.ini migrate

随后创建临时管理员 admin,具备管理员权限并设置为首次登录必须修改密码;INSTALL_LOCK 已设为 true。随机初始密码只保存在美国服务器:

/root/gitea-initial-admin.txt

文件权限为 0600 root:root。登录并修改密码后应删除该凭据文件。

初始化前备份目录:

/root/gitea-us-pre-init-20260726-041434

最终验证结果:数据库中存在一个管理员且 must_change_password=trueGitea 日志无初始化错误,https://git.us.chermack.top/user/login 从服务器内外访问均成功。

12. 美国管理后台周期性退出的根因(2026-07-26)

故障现象:https://www.us.chermack.top/ 失效,Nginx 80/443 和 Trojan 8443 正常,但 trojan-webfailed127.0.0.1:8081 无监听。

现场排查排除了磁盘耗尽、内存 OOM、Docker 容器重启、Nginx/Caddy 和本次 ACME 定时任务。关键证据:

宿主机 cgroupcgroup2fs
容器基础系统:CentOS 7 / systemd 219
容器 systemctlsystemctl.py 1.5.7113Python 替代实现)
容器启动日志:Failed to allocate manager object, freezing
容器内状态:多个 trojan/web 僵尸进程,无 journal 日志

当前镜像的 PID 1 systemd 无法在宿主机 cgroup v2 环境中正常建立 manager/usr/bin/systemctl 实际是一次性 Python 替代脚本,不是持续运行的服务管理器。因此 unit 中的 Restart=on-failure 不能可靠监督进程。宿主机现有 trojan-container-services.service 也是 Type=oneshot,只在开机时执行一次启动,运行中 Web 退出后不会再次拉起。

以前台方式直接运行以下命令持续 15 秒无异常,证明 Go Web 程序、数据库和 8081 端口本身健康:

docker exec trojan /usr/local/bin/trojan web \
  --host 127.0.0.1 --port 8081

探针启动的进程随后继续运行,8081、本地 /auth/check 和公网 HTTPS 均恢复 200;但替代 systemctl 仍错误显示 failed,再次证明问题位于服务管理层。

临时永久化建议:由宿主机真实 systemd 使用前台 docker exec 直接监督 trojan-web(以及 Trojan core),设置 Restart=always 并将 stdout/stderr 写入宿主机 journal。最终解决方案是使用已规划的新镜像,移除 CentOS 7、冻结的容器 systemd 和运行时下载的 systemctl.py。

13. 后续维护事项

  1. 两台服务器的 trojan-mariadb 仍将 3306 映射到公网;为避免额外中断,迁移中未改动。确认无外部依赖后,应限制为 127.0.0.1:3306 或移除映射。
  2. www.*git.* 使用不同的证书管理者:前者为 Trojan 容器内 acme.sh,后者为 Caddy。
  3. 两台服务器均已部署 trojan-container-services.service。重启服务器后,优先检查该服务及容器内两个 Trojan 服务状态。