بنقرة واحدة
umac-ai-deploy-prod
UMAC AI 生產部署 SOP — backend + frontend + CDK + ECS 全流程
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
UMAC AI 生產部署 SOP — backend + frontend + CDK + ECS 全流程
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Dev-agent / checker-agent collaboration loop driven by downstream project docs/STATE.md. Dev agent implements and records work items; an independent checker agent verifies each item with real lint/typecheck/test/build evidence and writes findings back; loop continues until all items are VERIFIED or escalation limits are hit.
Synchronizes review feedback, QA findings, user corrections, and code-review suggestions into durable project docs before Build, merge, or ship.
Intake workflow for existing projects before continuing development. Analyze current source state, derive a truthful docs baseline, identify QA/regression gaps, and create a safe continuation plan.
防止修復過的 bug 重新出現(regression)。 規則:每個修過的 bug 必須留下「regression test」+「root cause note」+「為何會發生」分析, 確保日後 refactor / 改需求時唔會重新踩坑。 David 在 2026-06-06 kanban task 明確指出「舊的 bug 又出現」嘅困擾。
定時壓縮長時間任務的 context,避免 token 爆炸。寫入 context-summary.md 保留決策和當前狀態,丢棄細節。
Task Orchestration Subagent — Coordinates all subagents, manages task board, handles parallel/sequential execution, tracks dependencies and failures. The conductor of the development orchestra.
| name | umac-ai-deploy-prod |
| description | UMAC AI 生產部署 SOP — backend + frontend + CDK + ECS 全流程 |
⚠️ DEPRECATED 2026-06-19 —
umac-ai-clusterECS cluster、SES verified identities、Route53 hosted zone、S3 bucket 全部不存在(0 個)。DNS 解析去 Hetzner + hosting reseller,項目已搬離 AWS。Recipe 過時,等 David 確認 hosting 位置 + supply access 再 update。
UMAC AI 項目(澳門大學 AI 大賽活動網站)的生產環境部署 SOP。
ap-east-1us-east-1https://api.board-ai.sitehttps://board-ai.siteumac-ai-clusterumac-ai-backend, umac-ai-frontendcd ~/projects/umac_ai
git add -A && git commit -m "description"
git push origin main
# 先確認有哪些 pending migrations
aws ecs run-task \
--cluster umac-ai-cluster \
--task-definition UMacAiEcsStackBackendTaskDefEF56D88D \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-01255018d4a3a1b1f,subnet-0c5ce99b7d83c693b],securityGroups=[sg-01d213a5c6e416f40]}" \
--overrides '{"containerOverrides":[{"name":"umac-ai-backend","command":["sh","-c","cd /app && ./node_modules/.bin/prisma migrate deploy --schema prisma/schema.prisma"],"environment":[{"name":"DATABASE_URL","value":"postgresql://umacai:PASSWORD@umacaidatabasestack-ummaaidbinstancecd68fce1-pxp9c9hn2dv6.cd8ge4mwq7jq.ap-east-1.rds.amazonaws.com:5432/umac_ai"}]}]}' \
--region ap-east-1
# 等待約 45 秒後 describe-tasks 確認 ExitCode: 0
注意:npx prisma 在 Fargate 內會失敗(ExitCode: 127),必須用 ./node_modules/.bin/prisma 並先 cd /app。
cd ~/projects/umac_ai/backend
sudo docker build --no-cache -t umac-ai-backend .
sudo docker tag umac-ai-backend:latest 631807311787.dkr.ecr.ap-east-1.amazonaws.com/umac-ai-backend:latest
aws ecr get-login-password --region ap-east-1 | sudo docker login --username AWS --password-stdin 631807311787.dkr.ecr.ap-east-1.amazonaws.com
sudo docker push 631807311787.dkr.ecr.ap-east-1.amazonaws.com/umac-ai-backend:latest
cd ~/projects/umac_ai/frontend
# .env.production 已有 VITE_API_BASE_URL=https://api.board-ai.site/api
sudo docker build -t umac-ai-frontend .
sudo docker tag umac-ai-frontend:latest 631807311787.dkr.ecr.ap-east-1.amazonaws.com/umac-ai-frontend:latest
sudo docker push 631807311787.dkr.ecr.ap-east-1.amazonaws.com/umac-ai-frontend:latest
cd ~/projects/umac_ai/infra
npx cdk deploy UMacAiEcsStack --region ap-east-1 --require-approval never
# CDK deploy 會 timeout(300s),但 CloudFormation 會繼續在後台執行
# 確認:aws cloudformation describe-stacks --stack-name UMacAiEcsStack --region ap-east-1
cd ~/projects/umac_ai
git add -A && git commit -m "description" && git push origin main
# CodeBuild 會自動:
# 1. Build backend Docker image + push to ECR
# 2. Build frontend + sync to S3 + CloudFront invalidation
# 3. 如果 infra/ 有變更 → CDK deploy
# 4. Prisma migrate + seed
# 5. ECS service update(拉新 image)
手動觸發 CodeBuild(如需立即部署):
aws codebuild start-build --project-name umac-ai-deploy --region ap-east-1 --query 'build.id' --output text
# 查狀態:
aws codebuild batch-get-builds --ids umac-ai-deploy:<build-id> --region ap-east-1 --query 'builds[0].[status,currentPhase]' --output text
CodeBuild 包含完整的檢測邏輯:
git diff 檢測哪些模組有變更# Backend
aws ecs update-service --cluster umac-ai-cluster --service umac-ai-backend --force-new-deployment --region ap-east-1
# Frontend
aws ecs update-service --cluster umac-ai-cluster --service umac-ai-frontend --force-new-deployment --region ap-east-1
# 前端靜態資源需同步到 S3,ECS frontend 容器更新的只是 container 本身
cd ~/projects/umac_ai/frontend
npm run build
aws s3 sync dist/ s3://umac-ai-frontend-631807311787-ap-east-1/ --region ap-east-1
aws cloudfront create-invalidation --distribution-id E2KORZ2WAC4CZS --paths "/*"
前端有 UI 改動時,否則用戶看到的是 CloudFront 緩存的舊版。
# Basic health
curl -s https://api.board-ai.site/health
# 測試登入
curl -s -X POST "https://api.board-ai.site/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@umac.ai","password":"AdminPass123"}'
# 測試 presign 上傳(需要新 token)
LOGIN_RESP=$(curl -s -X POST "https://api.board-ai.site/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@umac.ai","password":"AdminPass123"}')
TOKEN=$(echo $LOGIN_RESP | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))")
curl -s -X POST "https://api.board-ai.site/api/upload/presign" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"filename":"test.pdf","contentType":"application/pdf","size":1234}'
# CloudFront 測試(等同瀏覽器訪問)
curl -s -I "https://d25s1d60o4mvcq.cloudfront.net/api/courses"
CDK 只負責更新 AWS infrastructure(建立 S3 bucket、更新 task definition env、加 IAM policy)。CDK 不會 build 或 push Docker image。
每次代碼變更後,必須手動:
如果忘記這步,ECS 會繼續跑舊 image。
cd ~/projects/umac_ai/backend
bun --env-file=.env src/index.ts
.env 必須包含:
SES_REGION=us-east-1
SES_FROM_EMAIL=noreply@board-ai.site
JWT_SECRET=...
DATABASE_URL=...
email From 為 noreply@board-ai.site,envelope sender 預設是 010001...@amazonses.com,導致 DMARC FAIL。
解決:在 Route53 加 DKIM CNAME 記錄 + DMARC TXT 記錄。
umac-ai-cluster ECS cluster、SES verified identities、Route53 hosted zone、S3 bucket 全部不存在(0 個)。api.board-ai.site DNS 解析去 Hetzner 95.41.26.30 + hosting reseller (16.163.242.148 AMAZO-4 block),項目已搬離 AWS。Recipe 過時 — AWS infra 0/6 services 全部 missing,等 David 確認 hosting 位置 + supply access 再 update。
情境: 用戶投訴功能唔 work,你以為係 code bug,先查 AWS 卻發現成個 project 已搬走 — code bug 唔存在, infra drift 嘅 root cause 喺別處。
6 個 5-second probes(全部唔需要 project source code access,只需要 AWS credentials 同 dig):
# 1. DNS 指去邊
dig api.<project>.site +short # 預期 AWS 內: ELB/CloudFront IP
# 實際 Hetzner/DO/Linode = infra 已搬走
# 2. ECS cluster 仲在唔在
aws ecs list-clusters --region ap-east-1 # 預期有 project-cluster, 0 = gone
# 3. SES verified identities
aws sesv2 list-email-identities --region us-east-1
# 預期有 project-domain.com 或 no-reply@...
# 0 = SES 沙盒空, 邊個 email 都 send 唔出
# 4. SES Production Access
aws sesv2 get-account --region us-east-1 --query 'ProductionAccessEnabled,SendQuota' --output text
# false + Max24HourSend: 200 = 沙盒 mode
# 5. Route53 hosted zones
aws route53 list-hosted-zones --query 'HostedZones[?Name==`<project>.site.`].Id' --output text
# 0 = DNS 都唔喺 AWS
# 6. S3 buckets
aws s3api list-buckets --query 'Buckets[?contains(Name, `<project>`)].Name' --output text
# 0 = frontend hosting 都唔喺 AWS
Decision matrix:
| 6 probes 結果 | 結論 | Action |
|---|---|---|
| 全部預期值 | infra 仲喺 AWS | 查 code bug / env 變更 / recent deploy |
| 1-2 missing | partial drift | 逐個 probe, fix 缺失嗰個 (e.g. verify SES identity 走咗就 re-verify) |
| 3+ missing | infra 已搬走 | STOP。搵實際 hosting (SSH / control panel / GitHub repo)。悶頭做 AWS recipe 係 waste token |
Lesson codification: 任何「用戶投訴功能壞咗」嘅 task,第一步唔係睇 code,係跑呢 6 probes 10 秒。If 3+ missing → project 唔再你以為嘅 hosting,investigation 路徑完全唔同。
desired=2 但 running=0?先查 ECS stopped tasks + CloudWatch logs。曾發生 root cause:backend Dockerfile 用 bun build --target=node --format=cjs,但 runtime 是 CMD ["bun", "dist/index.js"],導致 Elysia/Bun app 啟動後 crash:
TypeError: Bun.serve() needs either routes object or fetch handler
修復:Dockerfile 必須用 Bun target:
RUN bun build src/index.ts --target=bun --outfile=dist/index.js
CMD ["bun", "dist/index.js"]
驗證:
cd ~/projects/umac_ai/backend
bun build src/index.ts --target=bun --outfile=dist/index.js
PORT=3999 timeout 5s bun dist/index.js
# 看到 startup log 並保持運行直到 timeout,不能出現 Bun.serve TypeError
修好後 rebuild/push backend image + force ECS deploy,確認:
aws ecs describe-services --cluster umac-ai-cluster --services umac-ai-backend --region ap-east-1 \
--query 'services[0].{desired:desiredCount,running:runningCount,pending:pendingCount,deployments:deployments[*].rolloutState}'
curl -fsS https://api.board-ai.site/health
先分辨是 API 掛了還是密碼錯:
curl -fsS https://api.board-ai.site/health — 如果 503,先修 backend。admin@umac.ai / AdminPass123;admin123 會回 Invalid email or password。根因:CloudFront origin 使用 ALB DNS name(如 UMacAi-UmmaA-...elb.amazonaws.com),但 ALB ACM 證書是 api.board-ai.site,TLS CN 不匹配導致 CloudFront 無法完成 TLS 握手。
修復(CDK 或 AWS CLI):
api.board-ai.sitehttps-only 改為 match-viewerAWS CLI 直接修復(立即生效):
# 取得目前 config
aws cloudfront get-distribution --id E2KORZ2WAC4CZS --region ap-east-1 > /tmp/cf-config.json
# 修改 Origin items[0].DomainName = "api.board-ai.site"
# 修改 Origin items[0].CustomOriginConfig.OriginProtocolPolicy = "match-viewer"
aws cloudfront update-distribution --id E2KORZ2WAC4CZS --distribution-config file:///tmp/cf-config.json
CDK 修復(同步到代碼):
// infra/lib/frontend.ts
const albDomain = 'api.board-ai.site'; // 不要用 ALB DNS name
// origin: { domainName: albDomain, originProtocolPolicy: 'match-viewer' }
測試 API 時一定要用「立即取得的新 token」,不要重複使用舊 token。
# 正確方式:登入後立即用同一個 shell session 測試
LOGIN_RESP=$(curl -s -X POST "https://api.board-ai.site/api/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin@umac.ai","password":"AdminPass123"}')
TOKEN=$(echo $LOGIN_RESP | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))")
curl -s -X POST "https://api.board-ai.site/api/upload/presign" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"filename":"test.pdf","contentType":"application/pdf","size":1234}'
檢查是否忘記 force new deployment。CDK deploy 只更新 task definition,現有 ECS tasks 不會自動重啟。
檢查 DKIM 是否 Pending → 需要在 Route53 加 DKIM CNAME 記錄。
正常,CloudFormation 在後台繼續執行。等 2-3 分鐘後確認 UPDATE_COMPLETE。
~/projects/umac_ai/backend/~/projects/umac_ai/frontend/~/projects/umac_ai/infra/631807311787.dkr.ecr.ap-east-1.amazonaws.com/umac-ai-backend 和 .../umac-ai-frontend