fix(ci): switch deploy images to cn registry
This commit is contained in:
+19
-12
@@ -12,10 +12,10 @@ concurrency:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
REGISTRY: ${{ vars.REGISTRY || 'crpi-u265r07n4blchcqo.cn-shanghai.personal.cr.aliyuncs.com' }}
|
||||
REGISTRY_NAMESPACE: ${{ vars.REGISTRY_NAMESPACE || 'ck-registry' }}
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
@@ -32,26 +32,27 @@ jobs:
|
||||
id: vars
|
||||
shell: bash
|
||||
run: |
|
||||
OWNER_LC="${GITHUB_REPOSITORY_OWNER,,}"
|
||||
echo "api_image=${{ env.REGISTRY }}/${OWNER_LC}/fquiz-api" >> "$GITHUB_OUTPUT"
|
||||
echo "web_image=${{ env.REGISTRY }}/${OWNER_LC}/fquiz-web" >> "$GITHUB_OUTPUT"
|
||||
NS="${{ env.REGISTRY_NAMESPACE }}"
|
||||
echo "api_image=${{ env.REGISTRY }}/${NS}/fquiz-api" >> "$GITHUB_OUTPUT"
|
||||
echo "web_image=${{ env.REGISTRY }}/${NS}/fquiz-web" >> "$GITHUB_OUTPUT"
|
||||
echo "image_tag=${GITHUB_SHA}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: 安装 Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: 登录 GHCR
|
||||
- name: 登录镜像仓库
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: 构建并推送 API 镜像
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./api
|
||||
file: ./api/Dockerfile
|
||||
pull: true
|
||||
push: true
|
||||
build-args: |
|
||||
PIP_INDEX_URL=${{ secrets.PIP_INDEX_URL || vars.PIP_INDEX_URL || 'https://pypi.org/simple' }}
|
||||
@@ -67,6 +68,7 @@ jobs:
|
||||
with:
|
||||
context: ./web
|
||||
file: ./web/Dockerfile
|
||||
pull: true
|
||||
push: true
|
||||
build-args: |
|
||||
NEXT_PUBLIC_API_BASE_URL=${{ vars.NEXT_PUBLIC_API_BASE_URL || 'http://127.0.0.1:8000' }}
|
||||
@@ -88,6 +90,8 @@ jobs:
|
||||
SERVER_USER: ${{ secrets.SERVER_USER || vars.SERVER_USER }}
|
||||
SERVER_SSH_KEY: ${{ secrets.SERVER_SSH_KEY }}
|
||||
SERVER_PASSWORD: ${{ secrets.SERVER_PASSWORD }}
|
||||
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
[ -n "${SERVER_HOST}" ] || { echo "::error::缺少 SERVER_HOST(请在 Secrets 或 Variables 中配置)"; exit 1; }
|
||||
@@ -96,6 +100,8 @@ jobs:
|
||||
echo "::error::缺少登录凭据:请至少配置 SERVER_SSH_KEY 或 SERVER_PASSWORD"
|
||||
exit 1
|
||||
fi
|
||||
[ -n "${REGISTRY_USERNAME}" ] || { echo "::error::缺少 REGISTRY_USERNAME"; exit 1; }
|
||||
[ -n "${REGISTRY_PASSWORD}" ] || { echo "::error::缺少 REGISTRY_PASSWORD"; exit 1; }
|
||||
|
||||
- name: 拉取代码
|
||||
uses: actions/checkout@v4
|
||||
@@ -141,8 +147,9 @@ jobs:
|
||||
IMAGE_TAG: ${{ needs.build-and-push.outputs.image_tag }}
|
||||
NEXT_PUBLIC_API_BASE_URL: ${{ vars.NEXT_PUBLIC_API_BASE_URL || 'http://127.0.0.1:8000' }}
|
||||
FLOWER_BASIC_AUTH: ${{ secrets.FLOWER_BASIC_AUTH || vars.FLOWER_BASIC_AUTH || 'admin:admin' }}
|
||||
GHCR_USERNAME: ${{ github.actor }}
|
||||
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
REGISTRY: ${{ env.REGISTRY }}
|
||||
REGISTRY_USERNAME: ${{ secrets.REGISTRY_USERNAME }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
with:
|
||||
host: ${{ secrets.SERVER_HOST || vars.SERVER_HOST }}
|
||||
username: ${{ secrets.SERVER_USER || vars.SERVER_USER }}
|
||||
@@ -151,7 +158,7 @@ jobs:
|
||||
command_timeout: 45m
|
||||
key: ${{ secrets.SERVER_SSH_KEY }}
|
||||
password: ${{ secrets.SERVER_PASSWORD }}
|
||||
envs: DEPLOY_PATH,API_IMAGE,WEB_IMAGE,IMAGE_TAG,NEXT_PUBLIC_API_BASE_URL,FLOWER_BASIC_AUTH,GHCR_USERNAME,GHCR_TOKEN
|
||||
envs: DEPLOY_PATH,API_IMAGE,WEB_IMAGE,IMAGE_TAG,NEXT_PUBLIC_API_BASE_URL,FLOWER_BASIC_AUTH,REGISTRY,REGISTRY_USERNAME,REGISTRY_PASSWORD
|
||||
script: |
|
||||
set -euo pipefail
|
||||
export DOCKER_CLIENT_TIMEOUT="${DOCKER_CLIENT_TIMEOUT:-600}"
|
||||
@@ -176,7 +183,7 @@ jobs:
|
||||
FLOWER_BASIC_AUTH=${FLOWER_BASIC_AUTH}
|
||||
ENV
|
||||
|
||||
echo "${GHCR_TOKEN}" | docker login ghcr.io -u "${GHCR_USERNAME}" --password-stdin
|
||||
echo "${REGISTRY_PASSWORD}" | docker login "${REGISTRY}" -u "${REGISTRY_USERNAME}" --password-stdin
|
||||
|
||||
COMPOSE_CMD="docker compose"
|
||||
if ! docker compose version >/dev/null 2>&1; then
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
- 宿主机 DB 暴露端口统一走 `POSTGRES_PORT`(默认 `5434`),用于规避与宿主机已有 PostgreSQL(常见 `5432`)冲突;容器内连接仍保持 `db:5432`。
|
||||
- CORS 来源控制采用“双轨配置”:`API_CORS_ORIGINS`(精确列表)+ `API_CORS_ORIGIN_REGEX`(正则,可选);`API_CORS_ORIGINS` 支持 `*` 和通配符域名并在后端转换为 `allow_origin_regex`。
|
||||
- GitHub Actions 使用 `appleboy/ssh-action` 部署时,慢网环境需显式设置 `command_timeout`(建议 `45m`)并为 `docker compose pull` 增加重试,避免出现 `Run Command Timeout` 直接中断发布。
|
||||
- 生产发布默认不再依赖 `ghcr.io`:工作流镜像仓库统一通过 `REGISTRY` / `REGISTRY_NAMESPACE` 控制,默认指向阿里云个人版容器仓库 `crpi-u265r07n4blchcqo.cn-shanghai.personal.cr.aliyuncs.com/ck-registry`;CI 与远端部署均使用 `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` 登录同一仓库,避免服务器侧访问 GHCR 出现 `Get "https://ghcr.io/v2/": EOF`。
|
||||
- `docker compose up -d` 不会重建 `build` 类型服务镜像;开发链路默认使用 `deploy/dev-deploy/compose.yml`,前端代码变更后需执行 `docker compose --env-file deploy/dev-deploy/.env -f deploy/dev-deploy/compose.yml up --build -d web`(必要时先 `docker compose --env-file deploy/dev-deploy/.env -f deploy/dev-deploy/compose.yml build --no-cache web`)。
|
||||
- `api` 构建若在拉取 `docker.m.daocloud.io/library/python:3.11-slim` 时出现 manifest `EOF`,优先重试 `docker compose --env-file deploy/dev-deploy/.env -f deploy/dev-deploy/compose.yml build api`;若持续失败,可在 `deploy/dev-deploy/.env` 覆盖 `PYTHON_BASE_IMAGE=python:3.11-slim` 走 Docker Hub 兜底。
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
COMPOSE_PROJECT_NAME=fquiz
|
||||
|
||||
API_IMAGE=ghcr.io/chengkml/fquiz-api:latest
|
||||
WEB_IMAGE=ghcr.io/chengkml/fquiz-web:latest
|
||||
API_IMAGE=crpi-u265r07n4blchcqo.cn-shanghai.personal.cr.aliyuncs.com/ck-registry/fquiz-api:latest
|
||||
WEB_IMAGE=crpi-u265r07n4blchcqo.cn-shanghai.personal.cr.aliyuncs.com/ck-registry/fquiz-web:latest
|
||||
|
||||
POSTGRES_IMAGE=docker.m.daocloud.io/pgvector/pgvector:pg16
|
||||
REDIS_IMAGE=docker.m.daocloud.io/library/redis:7-alpine
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
## Work Log - 发布链路切换国内镜像仓库(2026-05-16)
|
||||
|
||||
- 背景:
|
||||
- 当前 `dev` 分支 GitHub Actions 发布阶段在远端执行 `docker login ghcr.io` / `docker compose pull` 时失败。
|
||||
- 典型报错为:`Error response from daemon: Get "https://ghcr.io/v2/": EOF`。
|
||||
- 参考仓库 `multica-ck` 已采用“可配置国内镜像仓库 + 账号密码登录”的工作流模式。
|
||||
|
||||
- 本次改动:
|
||||
- `/.github/workflows/main.yml`
|
||||
- 将工作流默认镜像仓库从固定 `ghcr.io` 改为 `REGISTRY` / `REGISTRY_NAMESPACE` 可配置模式。
|
||||
- 默认值对齐 `multica-ck`:`crpi-u265r07n4blchcqo.cn-shanghai.personal.cr.aliyuncs.com/ck-registry`。
|
||||
- 构建推送阶段改为使用 `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` 登录镜像仓库。
|
||||
- 部署阶段新增镜像仓库凭据校验,并将远端 `docker login ghcr.io` 改为登录 `${REGISTRY}`。
|
||||
- API / Web 镜像构建补充 `pull: true`,降低 runner 侧基底镜像陈旧风险。
|
||||
- `/deploy/pro-deploy/.env`
|
||||
- 将默认 `API_IMAGE` / `WEB_IMAGE` 从 GHCR 地址替换为阿里云个人版容器仓库地址,保证非 CI 手工部署默认也不再回落到 GHCR。
|
||||
|
||||
- 验证:
|
||||
- `git diff --check -- .github/workflows/main.yml deploy/pro-deploy/.env` 通过,无空白/格式错误。
|
||||
- 仓库内已清除工作流与生产部署默认镜像中的 `ghcr.io` 活动引用。
|
||||
- 本次未直接触发 GitHub Actions 真实发布,远端连通性需在下一次 CI 执行中验证。
|
||||
|
||||
- 风险与关注点:
|
||||
- GitHub 仓库需预先配置 `REGISTRY_USERNAME` / `REGISTRY_PASSWORD` Secrets,否则构建登录阶段会失败。
|
||||
- 若未来镜像仓库或命名空间变化,只需更新仓库 Variables `REGISTRY` / `REGISTRY_NAMESPACE`,无需再改工作流逻辑。
|
||||
Reference in New Issue
Block a user