docs: 更新 CI 部署文档至 v5.3.0
同步实际部署配置变更: - Docker Compose 使用 network_mode: host 避免 VPC 冲突 - Act Runner config 补充 options + valid_volumes 挂载配置 - 移除 systemd 不必要的 BindPaths - CI health check 改用 bun fetch - 新增 Docker bridge/VPC 冲突和 health check 故障排查
This commit is contained in:
parent
9d1f52d95b
commit
b75a7ada75
@ -361,6 +361,11 @@ runner:
|
||||
container:
|
||||
# 容器使用宿主机网络(解决容器无法访问 127.0.0.1:3200 Gitea 的问题)
|
||||
network: "host"
|
||||
# 挂载宿主机目录到 job 容器(CI deploy 步骤需要读取 docker-compose.yml)
|
||||
options: "-v /opt/duoqi-api:/opt/duoqi-api"
|
||||
# 允许挂载的 volume 白名单
|
||||
valid_volumes:
|
||||
- /opt/duoqi-api
|
||||
# 不强制每次拉取镜像(国内网络下减少失败风险)
|
||||
force_pull: false
|
||||
```
|
||||
@ -379,9 +384,6 @@ ExecStart=/usr/local/bin/act_runner daemon --config /opt/act-runner/config.yaml
|
||||
Restart=always
|
||||
Environment=HOME=/root
|
||||
|
||||
# 关键:挂载 Docker socket,让 job 容器能访问宿主机的 Docker daemon
|
||||
BindPaths=/var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
@ -395,6 +397,11 @@ systemctl start act-runner
|
||||
systemctl status act-runner
|
||||
```
|
||||
|
||||
> **注意**:act_runner 是宿主机原生运行的二进制,不是容器。它本身已有完整的文件系统和网络访问权限。
|
||||
> - **不需要** `BindPaths` 挂载 Docker socket(宿主机进程可直接访问)
|
||||
> - **不需要** `BindPaths` 挂载 `/opt/duoqi-api`(同上)
|
||||
> - job 容器需要访问宿主机目录,通过 `config.yaml` 中的 `container.options` 和 `valid_volumes` 配置
|
||||
|
||||
### 环境隔离策略
|
||||
|
||||
#### RDS 数据库隔离
|
||||
@ -472,21 +479,22 @@ LOG_LEVEL=debug
|
||||
|
||||
**服务器 compose 文件** `/opt/duoqi-api/docker-compose.yml`:
|
||||
|
||||
> 代码库中对应文件为 `docker-compose.prod.yml`,部署时手动重命名为 `docker-compose.yml`。
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
# 使用 host 网络模式,避免 Docker bridge 子网与阿里云 VPC 内网 IP 段冲突
|
||||
|
||||
services:
|
||||
# ===== 生产环境 =====
|
||||
api-prod:
|
||||
build:
|
||||
context: /opt/gitea/data/git/repositories/admin/duoqi-api.git
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: duoqi-api:prod
|
||||
container_name: duoqi-api-prod
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
env_file: .env.prod
|
||||
ports:
|
||||
- "3000:3000"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
||||
interval: 30s
|
||||
@ -503,17 +511,16 @@ services:
|
||||
limits:
|
||||
memory: 400M
|
||||
|
||||
# ===== 测试环境(按需启停) =====
|
||||
# ===== 测试环境(Docker profiles 按需启停) =====
|
||||
api-test:
|
||||
build:
|
||||
context: /opt/gitea/data/git/repositories/admin/duoqi-api.git
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: duoqi-api:test
|
||||
container_name: duoqi-api-test
|
||||
restart: "no" # 不自动重启,手动控制
|
||||
restart: "no"
|
||||
network_mode: host
|
||||
env_file: .env.test
|
||||
ports:
|
||||
- "3001:3001"
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:3001/health"]
|
||||
interval: 30s
|
||||
@ -530,7 +537,7 @@ services:
|
||||
limits:
|
||||
memory: 300M
|
||||
profiles:
|
||||
- test # 使用 profiles 按需启停
|
||||
- test
|
||||
```
|
||||
|
||||
**启停命令:**
|
||||
@ -621,9 +628,11 @@ git push origin main
|
||||
| 生产部署手动确认 | 防止误操作,确保人工验证后才上线 |
|
||||
| 使用 Gitea Actions | 兼容 GitHub Actions 语法,学习成本低 |
|
||||
| Runner 使用 `network: host` | 容器共享宿主机网络,解决容器无法访问 Gitea 的问题 |
|
||||
| API 容器使用 `network_mode: host` | 避免 Docker bridge 默认子网(172.x.0.0/16)与阿里云 VPC 内网 IP 段冲突 |
|
||||
| Runner 使用 `github_mirror` | 从 gitea.com 镜像拉取 Actions,解决国内无法访问 GitHub 的问题 |
|
||||
| 自定义 Runner 镜像(bun + git + docker CLI) | 避免 checkout REST API 不兼容,支持 CI 中执行 docker 命令 |
|
||||
| Runner 挂载 Docker socket | Job 容器通过 socket 访问宿主机 Docker daemon,执行构建操作 |
|
||||
| Runner config 的 `options` + `valid_volumes` | 让 job 容器能挂载宿主机的 `/opt/duoqi-api` 目录,读取 docker-compose.yml |
|
||||
| CI health check 使用 `bun -e "fetch(...)"` | runner 镜像未安装 curl,用 bun 内置 fetch API 做 HTTP 健康检查 |
|
||||
| 固定 Bun 版本(1.3) | 确保 CI 环境可复现,避免 latest 版本变化导致意外失败 |
|
||||
|
||||
### 部署操作
|
||||
@ -840,11 +849,10 @@ services:
|
||||
# Phase 2: 多实例 docker-compose.yml
|
||||
# API 服务器上的配置
|
||||
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
api:
|
||||
image: your-registry/duoqi-api:latest
|
||||
network_mode: host
|
||||
deploy:
|
||||
replicas: 2 # 运行 2 个实例
|
||||
resources:
|
||||
@ -1036,6 +1044,48 @@ mysql -h your-rds-endpoint -u duoqi_prod -p -e "SELECT 1;"
|
||||
# 阿里云 RDS 控制台 → 数据安全性 → 白名单设置
|
||||
```
|
||||
|
||||
#### 7. Docker bridge 网络与 VPC 内网冲突
|
||||
|
||||
> **症状**:服务器无法连接 RDS(或 VPC 内其他服务),ping 显示源 IP 为 `172.x.0.1`(Docker 网桥 IP)而非宿主机内网 IP。
|
||||
|
||||
```bash
|
||||
# 查看路由表,检查是否有 Docker 网桥路由劫持了 VPC 流量
|
||||
route -n
|
||||
# 如果看到类似以下行,说明 Docker bridge 子网与 RDS IP 段冲突:
|
||||
# 172.23.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-xxxxxx
|
||||
|
||||
# 查看哪个 Docker 网络创建了冲突子网
|
||||
docker network ls
|
||||
docker network inspect <network-name>
|
||||
|
||||
# 解决方案 1:使用 network_mode: host(推荐,已在本方案中采用)
|
||||
# 在 docker-compose.yml 中为服务添加 network_mode: host
|
||||
# 这样不会创建 Docker bridge 网络,从根本上避免 IP 段冲突
|
||||
|
||||
# 解决方案 2:指定不冲突的子网
|
||||
# docker network create --subnet=192.168.200.0/24 my-network
|
||||
```
|
||||
|
||||
#### 8. CI health check 失败
|
||||
|
||||
```bash
|
||||
# 检查 health 路径是否正确(health 路由注册时无 /v1 前缀)
|
||||
# 正确:/health 错误:/v1/health
|
||||
|
||||
# 检查容器是否在运行
|
||||
docker ps -a --filter name=duoqi-api-prod
|
||||
|
||||
# 检查端口是否在监听(host 网络模式下直接看宿主机端口)
|
||||
ss -tlnp | grep 3000
|
||||
|
||||
# 查看容器日志
|
||||
docker logs duoqi-api-prod --tail 50
|
||||
|
||||
# 注意:CI health check 使用 bun -e "fetch(...)" 而非 curl
|
||||
# 如果 bun 的 promise 处理有问题,使用 top-level await:
|
||||
# bun -e "try{const r=await fetch('http://localhost:3000/health');process.exit(r.ok?0:1)}catch{process.exit(1)}"
|
||||
```
|
||||
|
||||
### 回滚操作
|
||||
|
||||
```bash
|
||||
@ -1113,6 +1163,6 @@ docker compose up -d api-prod
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v5.2.0 (双分支工作流 + 国内网络适配 + Docker 执行器完善)
|
||||
**最后更新**: 2026-04-17
|
||||
**文档版本**: v5.3.0 (host 网络模式 + Act Runner 挂载配置 + 故障排查更新)
|
||||
**最后更新**: 2026-04-18
|
||||
**维护者**: Duoqi Team
|
||||
|
||||
Loading…
Reference in New Issue
Block a user