# 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. 最终架构 ```mermaid 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 透传到 Trojan;Trojan 对非 Trojan TLS 流量回落到本机管理后台。 ## 3. 迁移前备份与检查 在变更前检查原容器和配置: ```bash docker ps docker inspect trojan docker exec trojan cat /usr/local/etc/trojan/config.json docker exec trojan systemctl cat trojan-web.service ``` 已创建的备份目录: ```text /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 配置调整为: ```json { "local_port": 8443, "remote_port": 8081 } ``` 管理后台 systemd unit 调整为: ```ini ExecStart=/usr/local/bin/trojan web --host 127.0.0.1 --port 8081 ``` 重载和启动命令: ```bash 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 统一入口 安装并启用: ```bash apt-get update apt-get install -y nginx libnginx-mod-stream systemctl enable --now nginx nginx -t ``` 443 使用 `stream` 和 `ssl_preread` 按 SNI 分流。香港示例(美国替换为 `www.us.chermack.top` 与 `git.us.chermack.top`): ```nginx 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:8082`;`git.*` 反向代理到 Caddy `127.0.0.1:8080`。 每次配置改动后: ```bash nginx -t && systemctl reload nginx ``` ## 6. Gitea 与 Caddy `/opt/gitea` 使用 Docker Compose 运行: - Gitea `1.27.0`:`127.0.0.1:3000->3000`,`2222->22`; - PostgreSQL `16`:仅 Docker 内网; - Caddy:`127.0.0.1:8080->80`、`127.0.0.1:9443->443`,反向代理到 Gitea。 ```bash cd /opt/gitea docker compose up -d docker compose ps ``` Caddy 管理 `git.*` 的 HTTPS 证书和自动续期;Nginx 对 Git 的 443 流量仅做 TLS 透传。Gitea 初始化时应填写: ```text ROOT_URL: https://git.<地区>.chermack.top/ SSH 域名: git.<地区>.chermack.top SSH 端口: 2222 ``` 香港 Gitea 曾按授权清空数据并重新初始化;再次重置前必须先备份 `/opt/gitea/gitea` 和 `/opt/gitea/postgres`。 ## 7. 美国服务器 SSH 端口处理 美国服务器原 OpenSSH 监听 `22`、`2222`、`2223`,与 Gitea Git SSH 的 `2222` 冲突。已保留宿主机 SSH `22`,移除宿主机的 `2222/2223` 监听,并将 `2222` 留给 Gitea。 变更前备份: ```text /etc/ssh/sshd_config.pre-gitea-20260726-014417 ``` 安全操作: ```bash sshd -t systemctl reload ssh ss -ltnp | grep sshd ``` 修改 SSH 配置时必须保持一条现有的 22 端口会话,验证完成后再断开。 ## 8. Trojan 证书续期 Trojan 的 `www.*` 证书仍由容器内 `acme.sh` 管理;Caddy 只管理 `git.*`。由于宿主机 80 已交给 Nginx,Trojan standalone 验证改用本地 8082: ```bash 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 都自动启动,但: ```bash docker exec trojan systemctl is-active trojan # inactive docker exec trojan systemctl is-active trojan-web # inactive ``` 此时没有 `8443` 和 `8081` 监听,因此 `www.hk.chermack.top` 不可用。 ### 临时恢复 ```bash 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`。 ```ini [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 ``` 启用并验证: ```bash 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 ``` 本次已验证该兜底服务为 `enabled`、`active`;Trojan 和 `trojan-web` 均为 `active`,且外部 HTTPS 访问 `https://www.hk.chermack.top/` 成功。 美国服务器也已部署同名的宿主机兜底 unit,并完成验证:`trojan-container-services.service` 为 `enabled`、`active`;Trojan 监听 `0.0.0.0:8443`,管理后台监听 `127.0.0.1:8081`;`https://www.us.chermack.top/` 与 `https://git.us.chermack.top/` 外部访问均成功。 ## 10. 日常检查与故障排查 ```bash # 统一入口、监听与容器 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-web` 和 `8081`;Trojan 客户端也异常时,再检查 `trojan` 和 `8443`: ```bash 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 使用明确配置文件完成初始化: ```bash gitea --work-path /data/gitea \ --config /data/gitea/conf/app.ini migrate ``` 随后创建临时管理员 `admin`,具备管理员权限并设置为首次登录必须修改密码;`INSTALL_LOCK` 已设为 `true`。随机初始密码只保存在美国服务器: ```text /root/gitea-initial-admin.txt ``` 文件权限为 `0600 root:root`。登录并修改密码后应删除该凭据文件。 初始化前备份目录: ```text /root/gitea-us-pre-init-20260726-041434 ``` 最终验证结果:数据库中存在一个管理员且 `must_change_password=true`,Gitea 日志无初始化错误,`https://git.us.chermack.top/user/login` 从服务器内外访问均成功。 ## 12. 美国管理后台周期性退出的根因(2026-07-26) 故障现象:`https://www.us.chermack.top/` 失效,Nginx 80/443 和 Trojan 8443 正常,但 `trojan-web` 为 `failed`,`127.0.0.1:8081` 无监听。 现场排查排除了磁盘耗尽、内存 OOM、Docker 容器重启、Nginx/Caddy 和本次 ACME 定时任务。关键证据: ```text 宿主机 cgroup:cgroup2fs 容器基础系统:CentOS 7 / systemd 219 容器 systemctl:systemctl.py 1.5.7113(Python 替代实现) 容器启动日志: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 端口本身健康: ```bash 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 服务状态。