Skip to content

Latest commit

 

History

History
350 lines (251 loc) · 9.16 KB

File metadata and controls

350 lines (251 loc) · 9.16 KB

Docker Compose + GitHub Actions 部署操作手册

目标

使用 GitHub Actions 构建并推送镜像到公开 GHCR package。部署时,GitHub-hosted runner 通过 SSH 登录服务器,只执行服务器上的部署脚本:

/usr/local/bin/deploy-from-github --repository <owner>/<repo> --image-prefix <image-prefix> --image-tag <commit-sha>

服务器脚本按目标 commit 从公开 GitHub 仓库下载 deploy/compose.server.yml,拉取公开 GHCR 镜像,生成运行目录并重启服务。

前端静态资源由独立的 Web Deploy workflow 发布到 nginx 静态目录,操作手册见 docs/deploy/frontend-github-actions.md

1. 服务器准备 Docker

在服务器执行:

docker version
docker compose version

部署用户必须能直接运行 Docker:

docker ps

如果当前用户没有 Docker 权限,将用户加入 docker 组后重新登录:

sudo usermod -aG docker <deploy-user>

2. 安装部署脚本

在本地仓库执行,把脚本复制到服务器:

scp deploy/deploy-from-github <deploy-user>@<server-host>:/tmp/deploy-from-github

在服务器执行:

sudo install -m 0755 /tmp/deploy-from-github /usr/local/bin/deploy-from-github
sudo mkdir -p /etc/sekai-platform
sudo mkdir -p /opt/sekai-platform
sudo chown <deploy-user>:<deploy-user> /opt/sekai-platform

验证脚本可执行:

/usr/local/bin/deploy-from-github --help

3. 配置服务器运行环境

在服务器创建 /etc/sekai-platform/server.env

sudo install -o <deploy-user> -g <deploy-user> -m 0600 /dev/null /etc/sekai-platform/server.env
sudo nano /etc/sekai-platform/server.env

deploy/server.env.example 填写以下内容:

POSTGRES_DB=sekai_platform
POSTGRES_USER=sekai_platform
POSTGRES_PASSWORD=<server-postgres-password>

JWT_ISSUER=sekai-platform
JWT_AUDIENCE=sekai-platform
JWT_SIGNING_KEY=<server-jwt-signing-key>

INTERNAL_AUTH_ISSUER=sekai-platform-internal
API_SERVICE_INTERNAL_PRIVATE_KEY=<api-service-private-key>
API_SERVICE_INTERNAL_PUBLIC_KEY=<api-service-public-key>
ASSET_SERVICE_INTERNAL_PRIVATE_KEY=<asset-service-private-key>
ASSET_SERVICE_INTERNAL_PUBLIC_KEY=<asset-service-public-key>
OPENAPI_SERVICE_INTERNAL_PRIVATE_KEY=<openapi-service-private-key>
OPENAPI_SERVICE_INTERNAL_PUBLIC_KEY=<openapi-service-public-key>
SYNC_WORKER_INTERNAL_PRIVATE_KEY=<sync-worker-private-key>
SYNC_WORKER_INTERNAL_PUBLIC_KEY=<sync-worker-public-key>

ASPNETCORE_ENVIRONMENT=Production
DATABASE_AUTO_MIGRATE=true
DATABASE_SEED=false

API_SERVICE_BIND_HOST=127.0.0.1
API_SERVICE_PORT=8080
OPENAPI_SERVICE_BIND_HOST=127.0.0.1
OPENAPI_SERVICE_PORT=8084
ELASTICSEARCH_INDEX_NAME=sekai-language-assets-v1
ELASTICSEARCH_JAVA_OPTS=-Xms512m -Xmx512m
ELASTICSEARCH_CLI_JAVA_OPTS=

CLAIM_CAPTCHA_REGION=cn
CLAIM_CAPTCHA_PREFIX=<aliyun-captcha-prefix>
CLAIM_CAPTCHA_SCENE_ID=<aliyun-captcha-scene-id>
CLAIM_CAPTCHA_ENDPOINT=captcha.cn-shanghai.aliyuncs.com
CLAIM_CAPTCHA_VERIFIER_PROVIDER=aliyun
CLAIM_CAPTCHA_ACCESS_KEY_ID=<ram-access-key-id>
CLAIM_CAPTCHA_ACCESS_KEY_SECRET=<ram-access-key-secret>
CLAIM_CAPTCHA_REQUEST_TIMEOUT=00:00:03
CLAIM_CAPTCHA_EKEY=<aliyun-v3-ekey>
CLAIM_CAPTCHA_ENCRYPTED_SCENE_ID_TTL_SECONDS=300

CLAIM_CAPTCHA_EKEY 是阿里云验证码 V3 加密模式使用的 ekey,不是 RAM AccessKey Secret;两者都只放在服务器环境变量或密钥系统中,不写入仓库。

生成内部 token 密钥时,在本地或服务器执行:

scripts/generate-internal-auth-keys.sh

不要把生成结果提交到 Git。

4. 配置部署 SSH key

在本地生成部署专用 key:

ssh-keygen -t ed25519 -C sekai-platform-deploy -f ./sekai-platform-deploy

把公钥加入服务器部署用户:

ssh-copy-id -i ./sekai-platform-deploy.pub <deploy-user>@<server-host>

生成 known_hosts 内容:

ssh-keyscan -p <ssh-port> <server-host> > ./sekai-platform-known-hosts

验证 SSH 能执行部署脚本:

ssh -i ./sekai-platform-deploy -p <ssh-port> <deploy-user>@<server-host> \
  '/usr/local/bin/deploy-from-github --help'

5. 配置 GitHub production environment

在 GitHub 仓库进入:

Settings -> Environments -> New environment -> production

添加 Environment variables:

Name Value
SEKAI_DEPLOY_PORT <ssh-port>
SEKAI_DEPLOY_USER <deploy-user>
SEKAI_DEPLOY_SCRIPT /usr/local/bin/deploy-from-github

添加 Environment secrets:

Name Value
SEKAI_DEPLOY_HOST <server-host>
SEKAI_DEPLOY_SSH_KEY ./sekai-platform-deploy 私钥全文
SEKAI_DEPLOY_KNOWN_HOSTS ./sekai-platform-known-hosts 全文

配置完成后删除本地临时私钥文件:

rm -f ./sekai-platform-deploy ./sekai-platform-deploy.pub ./sekai-platform-known-hosts

6. 构建镜像

推送到 main 后,GitHub Actions 自动执行:

build-test -> build-images

确认 build-images 成功,并且 GHCR 中存在以下公开镜像:

ghcr.io/<owner>/<repo>/api-service:<commit-sha>
ghcr.io/<owner>/<repo>/auth-service:<commit-sha>
ghcr.io/<owner>/<repo>/asset-service:<commit-sha>
ghcr.io/<owner>/<repo>/claim-service:<commit-sha>
ghcr.io/<owner>/<repo>/openapi-service:<commit-sha>
ghcr.io/<owner>/<repo>/search-service:<commit-sha>
ghcr.io/<owner>/<repo>/sync-worker:<commit-sha>
ghcr.io/<owner>/<repo>/elasticsearch:<commit-sha>

确认这些 package 的 Visibility 为 Public。服务器部署脚本不会配置 GHCR 读取凭证。

7. 首次部署

在 GitHub Actions 页面手动触发 Production Deploy workflow:

Actions -> Production Deploy -> Run workflow -> main

该 workflow 会重新执行构建和镜像发布,然后执行 deploy job。deploy job 只会通过 SSH 执行服务器脚本。

部署脚本完成后,API Service 容器启动时会自动执行 EF Core migration。生产环境不会自动执行 seed。

8. 服务器验证

在服务器执行:

cd /opt/sekai-platform
docker compose ps
docker compose logs --tail=100 api-service

确认 API Service 没有 migration 异常:

docker compose logs api-service | grep -iE 'migrat|exception|fail'

在服务器或反向代理所在机器执行:

curl -fsS http://127.0.0.1:8080/health

如需在本机连服务器验证,通过反向代理域名访问公开入口。

部署完成后可执行基础冒烟:

API_BASE_URL=http://127.0.0.1:8080 \
SMOKE_PASSWORD=<smoke-user-password> \
scripts/deployment-smoke.sh

抢活模块提供专项冒烟脚本。默认路径会验证 Claim Service 健康、验证码公开配置、Demo 按需生成,以及管理员创建、编辑、发布任务:

API_BASE_URL=http://127.0.0.1:8080 \
SMOKE_PASSWORD=<smoke-user-password> \
scripts/claiming-smoke.sh

本地或测试环境使用 Captcha:VerifierProvider=m4-stub 时,可以显式开启完整抢活判定、并发同职能、同用户二次抢剩余职能、公开 attempts 和管理员审计检查:

API_BASE_URL=http://127.0.0.1:8080 \
SMOKE_PASSWORD=<smoke-user-password> \
CLAIM_SMOKE_RUN_CLAIMS=1 \
scripts/claiming-smoke.sh

生产环境使用真实阿里云验证码时,不要复用同一个 captcha_verify_param。如果要跑完整抢活路径,需要先从前端完成三次独立拼图验证并注入一次性参数:

API_BASE_URL=https://<public-api-domain> \
SMOKE_PASSWORD=<smoke-user-password> \
CLAIM_SMOKE_RUN_CLAIMS=1 \
CLAIM_SMOKE_CAPTCHA_VERIFY_PARAM_1=<captcha-verify-param-1> \
CLAIM_SMOKE_CAPTCHA_VERIFY_PARAM_2=<captcha-verify-param-2> \
CLAIM_SMOKE_CAPTCHA_VERIFY_PARAM_3=<captcha-verify-param-3> \
scripts/claiming-smoke.sh

9. 手动部署指定镜像

在服务器执行:

/usr/local/bin/deploy-from-github \
  --repository <owner>/<repo> \
  --image-prefix ghcr.io/<owner>/<repo> \
  --image-tag <commit-sha>

先做 dry-run:

/usr/local/bin/deploy-from-github \
  --repository <owner>/<repo> \
  --image-prefix ghcr.io/<owner>/<repo> \
  --image-tag <commit-sha> \
  --dry-run

10. 回滚

找到上一个可用 commit SHA 后,在服务器执行:

/usr/local/bin/deploy-from-github \
  --repository <owner>/<repo> \
  --image-prefix ghcr.io/<owner>/<repo> \
  --image-tag <previous-good-sha>

确认:

cd /opt/sekai-platform
docker compose ps
curl -fsS http://127.0.0.1:8080/health

11. 数据库迁移

生产环境默认开启启动迁移,关闭 seed:

DATABASE_AUTO_MIGRATE=true
DATABASE_SEED=false

执行部署时,脚本会按目标 commit 从 GitHub 下载 deploy/compose.server.yml,更新 Compose 文件并重启服务。API Service 启动阶段执行 pending EF Core migrations。

迁移失败时:

  1. 本次 API Service 容器启动失败或健康检查失败。
  2. 查看日志:
cd /opt/sekai-platform
docker compose logs --tail=200 api-service
  1. 修复数据库或代码问题后,重新执行部署:
/usr/local/bin/deploy-from-github \
  --repository <owner>/<repo> \
  --image-prefix ghcr.io/<owner>/<repo> \
  --image-tag <commit-sha>

禁止在 Production 设置:

DATABASE_SEED=true