昨天我把 Docker 化的 Todo API 跑上 ECS Fargate。
今天的任務是:把它連到 AWS RDS(PostgreSQL),並用正確的 環境變數/機密管理 來設定連線。
步驟(Console)
進入 RDS → Create database
Engine:PostgreSQL
Template:Dev/Test(學習用)
DB instance identifier:todo-db
Master username:postgres;設定密碼(先記下)
Connectivity
rds-allow-from-ecs
先用預設就好,建立完成 🎉
Security Group 設定
到 EC2 → Security Groups
rds-allow-from-ecs
💡 RDS 建好後會有一個 Endpoint,像
todo-db.xxxxxx.ap-northeast-1.rds.amazonaws.com,等等要用。
prisma/schema.prisma 的 provider 要用 postgresql(昨天可能已經改過):
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
DATABASE_URL(範例)
postgresql://postgres:<你的密碼>@todo-db.xxxxxx.ap-northeast-1.rds.amazonaws.com:5432/todo
ECS → Task definitions → 你的 todo-api-task → Create new revision
Container → Environment variables
NODE_ENV=production
DATABASE_URL=postgresql://postgres:<pwd>@<rds-endpoint>:5432/todo
儲存 → 用這個新 revision 更新 Service(Deploy)
學習階段可以先 A、正式專案一定用 B。
Fargate 容器不會自己幫你建表,你需要跑 migration。
三種方式,選一種即可:
把 Task Definition 的 command 改為:
sh -c "npx prisma migrate deploy && node dist/index.js"
好處是自動;缺點是每次啟動都會跑一次(可,但不是最優雅)。
ECS → Tasks → Run new task
使用同一個 Task Definition
Override command:
npx prisma migrate deploy
跑完成功(Log 會顯示已套用 migration)→ 再用正常指令啟服務
在本機 .env 設 RDS 的 DATABASE_URL
跑:
npx prisma migrate deploy
優點是快;缺點是你的本機得能連上 RDS(安全群組要打開,或走 VPN/Bastion)
更新服務
todo-api-service → Deploy new task definition(使用剛剛新 revision)Last status: RUNNING
看 Log(CloudWatch)
應該看到:
Database connection OK
🚀 Server running on port 3000
驗證 CRUD
curl -X POST http://<Public-IP or ALB>:3000/todos \
-H "Content-Type: application/json" \
-d '{"task":"RDS connected!"}'
curl http://<Public-IP or ALB>:3000/todos
如果能新增 & 查到資料,就成功了 🎉
| 異常 | 可能原因 | 解法 |
|---|---|---|
ECONNREFUSED 或連不到 DB |
RDS SG 沒放行 ECS SG | RDS SG inbound 加:Postgres 5432,Source = ECS Service 的 SG |
| 任務起來就停止(Stopped) | DATABASE_URL 錯誤、Prisma 連線失敗 | 檢查 CloudWatch Logs,修正連線字串 |
CannotPullContainerError |
ECS 任務沒權限拉 ECR | Task Execution Role 附上 AmazonECSTaskExecutionRolePolicy |
| 本機測試 OK,上 ECS 失敗 | 你在本機 .env,但 ECS 沒帶環境變數 |
Task Definition 裡把 DATABASE_URL 帶進去(或用 Secret) |
| migrate 卡住 | Task 缺權限或沒連線 | 改用方式 2(一次性任務)跑 npx prisma migrate deploy,看 log |
DATABASE_URL(或 Secrets)prisma migrate deploy
/todos 能 CRUD,資料存在 RDS把 API 接上 RDS 之後,我總算體驗到「雲端服務真的在運作」的感覺。
今天最大的學習是 網路與權限的重要性: