fix(staging): use stable :dev tag for containers to enable Watchtower auto-update #2121
@@ -104,6 +104,43 @@ Staging 当前可以保持 no-op;Production 开启前必须先验证 SMTP/Redi
|
||||
|
||||
---
|
||||
|
||||
## Staging 服务器 Docker 凭证配置
|
||||
|
||||
Staging 服务器(116.62.226.203)需要配置 ACR 和 Gitea Registry 凭证,否则 docker pull 和 Watchtower 自动更新会失败。
|
||||
|
||||
### 凭证文件位置
|
||||
- Docker 配置文件:`/root/.docker/config.json`
|
||||
- 包含两个 registry 的认证信息:
|
||||
- `xiaoxia-registry.cn-hangzhou.cr.aliyuncs.com`(阿里云 ACR)
|
||||
- `git.xiaoxiajianji.com`(Gitea 容器镜像仓库)
|
||||
|
||||
### 服务器迁移后恢复步骤
|
||||
```bash
|
||||
# 1. 登录 ACR
|
||||
docker login xiaoxia-registry.cn-hangzhou.cr.aliyuncs.com -u <ACR_USERNAME>
|
||||
|
||||
# 2. 登录 Gitea Registry
|
||||
docker login git.xiaoxiajianji.com -u xiaoxia -p <GITEA_REGISTRY_TOKEN>
|
||||
|
||||
# 3. 重启 Watchtower(确保挂载最新 config.json)
|
||||
docker restart watchtower
|
||||
```
|
||||
|
||||
### Watchtower 配置
|
||||
- 容器名:`watchtower`
|
||||
- 检查间隔:300 秒(5 分钟)
|
||||
- 监控容器:`xiaoxia-api-staging`、`xiaoxia-worker-staging`、`xiaoxia-web-staging`
|
||||
- 必须挂载 `-v /root/.docker/config.json:/config.json` 才能拉取私有镜像
|
||||
- 必须挂载 `-v /var/run/docker.sock:/var/run/docker.sock` 才能管理容器
|
||||
- 容器使用 `:dev` 稳定 tag,Watchtower 通过检测 `:dev` tag 的 digest 变化来发现更新
|
||||
|
||||
### 镜像 Tag 策略
|
||||
- CI 每次构建推送三种 tag:`${GITHUB_SHA}`(精确版本)、`${GITHUB_REF_NAME}`(分支名)、`:dev`(滚动 tag,仅 develop 分支)
|
||||
- Staging 容器统一使用 `:dev` tag 启动,确保 Watchtower 能自动发现新版本
|
||||
- Migration(alembic)使用 commit SHA tag 执行,不依赖 Watchtower
|
||||
|
||||
---
|
||||
|
||||
## Gitea Actions 约定
|
||||
|
||||
- `develop` 分支触发 staging 部署。
|
||||
|
||||
@@ -368,6 +368,21 @@ fi
|
||||
|
||||
echo "All images pulled."
|
||||
|
||||
# ====== 打稳定 tag(:dev),供 Watchtower 监控 ======
|
||||
# Watchtower 只能检测同一个 tag 的 digest 变化。
|
||||
# commit SHA tag 每次构建都不同,Watchtower 无法感知更新。
|
||||
# 因此每次部署都将最新镜像 tag 为 :dev,容器统一使用 :dev 启动。
|
||||
DEV_API="${REGISTRY}/xiaoxia-saas-api:dev"
|
||||
DEV_WORKER="${REGISTRY}/xiaoxia-saas-worker:dev"
|
||||
DEV_WEB="${REGISTRY}/xiaoxia-saas-web:dev"
|
||||
docker tag "$REGISTRY_API" "$DEV_API"
|
||||
docker tag "$REGISTRY_WORKER" "$DEV_WORKER"
|
||||
docker tag "$REGISTRY_WEB" "$DEV_WEB"
|
||||
echo "✅ Tagged images as :dev for Watchtower monitoring"
|
||||
echo " API: $DEV_API"
|
||||
echo " Worker: $DEV_WORKER"
|
||||
echo " Web: $DEV_WEB"
|
||||
|
||||
# ====== 镜像内容校验 ======
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
@@ -533,7 +548,7 @@ docker run -d \
|
||||
--health-retries 3 \
|
||||
--health-start-period 40s \
|
||||
$LOG_OPTS \
|
||||
"$REGISTRY_API" &
|
||||
"$DEV_API" &
|
||||
PID_API_START=$!
|
||||
|
||||
# ── Worker: 通过 compose 启动(单一事实来源)──
|
||||
@@ -541,7 +556,7 @@ PID_API_START=$!
|
||||
# healthcheck 匹配 'celery.*worker'(不把 beat 算活)、资源限制 4C/8G。
|
||||
# WORKER_IMAGE 通过环境变量覆盖镜像 tag(compose.yml 默认 :dev)。
|
||||
echo "Starting worker via docker compose (from $INFRA_DOCKER_DIR)..."
|
||||
WORKER_IMAGE="$REGISTRY_WORKER" APP_VERSION="$IMAGE_TAG" compose up -d --no-deps worker &
|
||||
WORKER_IMAGE="$DEV_WORKER" APP_VERSION="$IMAGE_TAG" compose up -d --no-deps worker &
|
||||
PID_WORKER_START=$!
|
||||
|
||||
# ── Web: 暂保留 docker run(TODO: 后续收敛到 compose)──
|
||||
@@ -557,7 +572,7 @@ docker run -d \
|
||||
--health-timeout 5s \
|
||||
--health-retries 3 \
|
||||
$LOG_OPTS \
|
||||
"$REGISTRY_WEB" &
|
||||
"$DEV_WEB" &
|
||||
PID_WEB_START=$!
|
||||
|
||||
wait $PID_API_START $PID_WORKER_START $PID_WEB_START
|
||||
@@ -688,5 +703,5 @@ echo "=== Staging deployment complete ==="
|
||||
echo "API: http://127.0.0.1:8000"
|
||||
echo "Web: http://127.0.0.1:3001"
|
||||
echo "Worker: managed by docker compose (project=$COMPOSE_PROJECT)"
|
||||
echo "Version: $IMAGE_TAG"
|
||||
echo "Version: $IMAGE_TAG (running as :dev for Watchtower)"
|
||||
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | grep staging
|
||||
|
||||
Reference in New Issue
Block a user