Files
codex-app-server/deploy/new-host-checklist.md
T
2026-10-27 00:30:32 +08:00

112 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 新主机入网清单(HA 阶段 4)
新机加入前,老机继续全量服务;新机全部验证通过后才切流量。
清单里的路径与实测值以 2026-10-26 主机为准,变了同步改。
## 1. 系统与用户
- Ubuntu 24.04、Python 3.12、git、Docker(与老机同大版本)、
Node 18(装 codex 用)。
- 建 `codexsvc`(uid 1003、gid 1004)并加入 `docker` 组。
- NTP:`timedatectl` 确认 `NTPSynchronized=yes`(心跳、超时、
sweep 全依赖时钟,不同步会出现“活任务被误扫”)。
## 2. 代码与目录
- `/opt/codex-app-server`:部署 tar 解包,`chown -R codexsvc`。
- `/var/lib/codex-app-server/`:建 `tenants/`、`repos/`、
`codex-home/`(模板)、`backups/`(700)。
- `/etc/codex-app-server/env`(0600 root):与老机一致,尤其
`CLOUD_DB_PASSWORD`(新卷 Postgres 的初始化口令必须等于它,
见 `postgres-rebuild.md` 场景 B)、relay key、GitHub OAuth
secret、webhook secret。密钥绝不进仓库、不进部署 tar。
## 3. 数据库
- 有现成 Postgres 时:env 里改 `CLOUD_DB_HOST/PORT` 指向它。
- 没有时:按 `postgres-rebuild.md` 场景 B 重建(新卷 + 最新备份
恢复 + 四表校验),再起 server。
## 4. 服务 units(都在 `deploy/` 里有参考文件,unit 文件不在
## deploy tar 里,须单独 scp 到 `/etc/systemd/system/` 再
## daemon-reload + enable + start)
- `codex-cloud-server`(8765)与 `codex-cloud-server-2`(8766)
双机;`codex-autoscaler`(min 1 / max 2、per-worker capacity 2、
`--docker-runtime runsc`);`codex-host-worker`(local,
`--claim-executor-only`,经 `aa-exec -p codex-host` 跑);
`codex-pg-backup.timer`(每天 03:00 CST);
`monitor.timer`(每 5 分钟)。
- 注意:`codex-cloud-worker` 已停用(autoscaler 接管),绝不能
与 autoscaler 同时跑。
## 5. 沙箱与隔离
- AppArmor:加载 `docker-codex` 与 `codex-host` 两个 profile
(`deploy/apparmor/` 下);`codex-host` 的坑已修过(capability
放行只是 userns 内假 root;`network netlink raw` 必须允许且
deny raw 须写明 inet/inet6;`/tmp` 不隔离,见 HA-DESIGN)。
- Docker:`daemon.json` 注册 runsc(`/usr/local/bin/runsc` +
**必须成对**的 `/usr/local/bin/gvisor-bin/`,只拷 runsc 会报
sidecar 不可用);默认仍 runc,生产任务经 worker flag 走 runsc。
- 镜像:见第 7 节。
## 6. 出口代理(每机一份,改动时同批下发,不要手工各改各的)
- 拷 `/etc/tinyproxy/tinyproxy.conf` 与
`/etc/tinyproxy/tinyproxy-filter`(**644**,tinyproxy 用户可读;
Filter 是 **POSIX BASIC regex**,extended 写法会把允许域名也
挡成 403;没有合法的 `Upstream none` 写法,直接连接就是默认)。
- 白名单只放行 xcmapi.org、github.com、pypi.org、npmjs.org
及子域;iptables 只放行 `172.16.0.0/12` 与 `127.0.0.1`
(`iptables-save` 导出、到新机 `iptables-restore`)。
- Docker 任务容器出口走宿主 8888 代理(worker 的
`--egress-proxy-port 8888`)。
## 7. 镜像传输(现阶段:docker save/load,不建无鉴权 registry)
- 没有带鉴权 + TLS 的 registry 时,**不要**在本机跑无鉴权
registry(谁都能推恶意镜像,等于把 worker 的执行环境交给
任何人)。新机用 save/load 传镜像,流程已实弹验过:
```sh
# 老机导出(919MB,注意磁盘余量)
docker save codex-app-server:latest -o /tmp/codex-image.tar
# 传到新机(scp 或 chunk_send,传完 sha256 比对)
# 新机导入(幂等,已有同名镜像时只是重加已有层,不删东西)
docker load -i /tmp/codex-image.tar
docker images codex-app-server
```
- host 2 落地后,再评估带鉴权 + TLS 的 registry(或云厂商的
容器镜像服务),届时把“新机拉镜像”一步换成 `docker pull`。
## 8. 入口(nginx)
- 拷 vhost(含三个 codex location)与 `codex-upstream.conf`
(upstream 块只能在 http 段,不能放进 server 块)。
- 宝塔重生成 vhost 会吃掉 location,备份在
`/etc/codex-app-server/` 与 vhost 目录的 `.pre-*` 文件里,
被吃时从备份贴回,再 `nginx -t` + reload。
- 双机 nginx(浮动 IP keepalived,同机房;或 DNS 轮询 + 健康
检查,跨机房)**需要第二台主机才能演练**,现阶段单机 nginx
仍是单点,见 HA-DESIGN 阶段 4。
## 9. 入网验证(全部通过才切流量)
1. `monitor.sh` 全过(含 backup 项)。
2. 双 server health(8765、8766)均为 ok 且 db_ok。
3. autoscaler 正常(`--host-name` 已传宿主名,见 worker 进程
命令行),worker 注册表里有新机 worker。
4. 一个 Docker 任务端到端完成(worktree_host 应为新机主机名)。
5. `/pr` 同步路(本机 worktree)与队列路(改写 worktree_host
后排队、pr-runner 跑通)各一次。
6. 备份 timer 下次触发时间正常(`systemctl list-timers`)。
## 10. 回滚
- 新机任何一步失败:停新机服务,老机不受影响(老机从未停过,
流量也从未切过)。
- 切流量后发现问题:nginx upstream 先摘掉新机端口(或把三个
location 的 proxy_pass 指回老机单端口),reload 即可回单机。