iT邦幫忙

2025 iThome 鐵人賽

0
自我挑戰組

《轉職學習日記:JavaScript × Node.js × TypeScript × Docker × AWS ECS》系列 第 40

Day40 - 持續成長學習藍圖 - AWS 與 ECS(整合 RDS(PostgreSQL)與環境變數)

  • 分享至 

  • xImage
  •  

昨天我把 Docker 化的 Todo API 跑上 ECS Fargate
今天的任務是:把它連到 AWS RDS(PostgreSQL),並用正確的 環境變數/機密管理 來設定連線。


1) 先創一個 RDS PostgreSQL

步驟(Console)

  1. 進入 RDS → Create database

  2. Engine:PostgreSQL

  3. Template:Dev/Test(學習用)

  4. DB instance identifier:todo-db

  5. Master username:postgres;設定密碼(先記下)

  6. Connectivity

    • VPC:選你 ECS Cluster 用的那個
    • Public access:No(建議私有)
    • VPC security group:新建 rds-allow-from-ecs
  7. 先用預設就好,建立完成 🎉

Security Group 設定

  • EC2 → Security Groups

    • 找到 rds-allow-from-ecs
    • Inbound 加一條:PostgreSQL (5432)Source 指向「你的 ECS Service 所使用的 Security Group
    • 這代表:只有 ECS 服務能連 RDS,外界不行(安全)

💡 RDS 建好後會有一個 Endpoint,像 todo-db.xxxxxx.ap-northeast-1.rds.amazonaws.com,等等要用。


2) 更新 Prisma 設定與 DATABASE_URL

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

3) 把 DATABASE_URL 放到 ECS(兩種方式)

A. 先簡單用「Plain 環境變數」(示範用)

  • 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)

B. 比較正統:用 Secrets Manager 或 SSM(建議)

  1. 先把 DATABASE_URL 存到 Secrets ManagerSSM Parameter Store
  2. 在 Task Definition 的 Environment → ValueFrom 選剛存的機密
  3. 確認 Task Execution Role 有讀取該 Secret/Parameter 的權限

學習階段可以先 A、正式專案一定用 B。


4) 讓資料表上線:Prisma migration

Fargate 容器不會自己幫你建表,你需要跑 migration。
三種方式,選一種即可:

方式 1:在容器啟動時自動跑(偷懶法)

把 Task Definition 的 command 改為:

sh -c "npx prisma migrate deploy && node dist/index.js"

好處是自動;缺點是每次啟動都會跑一次(可,但不是最優雅)。

方式 2:用「一次性任務」跑 migrate(推薦)

  • ECS → Tasks → Run new task

  • 使用同一個 Task Definition

  • Override command:

    npx prisma migrate deploy
    
  • 跑完成功(Log 會顯示已套用 migration)→ 再用正常指令啟服務

方式 3:本機暫時指向 RDS,跑一次 migrate

  • 在本機 .env 設 RDS 的 DATABASE_URL

  • 跑:

    npx prisma migrate deploy
    
  • 優點是快;缺點是你的本機得能連上 RDS(安全群組要打開,或走 VPN/Bastion)


5) 重新部署 & 測試

更新服務

  • ECS → Services → 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

如果能新增 & 查到資料,就成功了 🎉


6) 常見錯誤排查表

異常 可能原因 解法
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

7) 小清單:今天做完該有哪些結果

  • [ ] RDS 建好、私有、SG 只允許 ECS 連線
  • [ ] ECS Task Definition 帶上 DATABASE_URL(或 Secrets)
  • [ ] 跑過 prisma migrate deploy
  • [ ] /todos 能 CRUD,資料存在 RDS
  • [ ] CloudWatch Logs 乾淨沒有錯誤

🎯 學習心得 / 今日收穫

把 API 接上 RDS 之後,我總算體驗到「雲端服務真的在運作」的感覺。
今天最大的學習是 網路與權限的重要性

  • Security Group 要讓 RDS 只接受 ECS 來的連線(私有、最小授權)
  • 機密不要硬寫在 Task(先用環境變數學習、正式用 Secrets Manager/SSM
  • Migration 可用「一次性任務」跑,乾淨又可追蹤

上一篇
Day39 - 持續成長學習藍圖 - AWS 與 ECS(讓 Todo API 跑上 ECS_整合 Fargate)
系列文
《轉職學習日記:JavaScript × Node.js × TypeScript × Docker × AWS ECS》40
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言