AWS ECS Notes
ECS Fargate is the AWS no-K8s path; the image and env contract are identical, ECS is just the scheduler. On EKS, prefer the Helm chart. This page covers the ECS-specific glue: task definition, ALB path split, RDS, and the migration one-shot.
Image registry
Fargate can pull directly from Docker Hub, but mirror to ECR for in-region pull latency, immutable-tag policies, and scan-on-push:
aws ecr get-login-password --region us-east-1 | \\
docker login --username AWS --password-stdin <ACCOUNT>.dkr.ecr.us-east-1.amazonaws.com
docker pull simchasolutions/db-studio:1.0.1
docker tag simchasolutions/db-studio:1.0.1 <ACCOUNT>.dkr.ecr.us-east-1.amazonaws.com/simcha-db-studio:1.0.1
docker push <ACCOUNT>.dkr.ecr.us-east-1.amazonaws.com/simcha-db-studio:1.0.1
Task definition essentials
- CPU / memory: 1 vCPU / 2048 MB is a sensible starting size. Scale up if you have many concurrent users.
- Container port mappings: 3000 (Next.js) and 5002 (API). Both go behind the same ALB.
- Secrets: Reference Secrets Manager or SSM Parameter Store ARNs in the
secretsblock of the task definition, never hard-codeJWT_SECRET/ENCRYPTION_KEY/DB_DEVOPS_DB_PASSWORDin the env block. - Logs:
awslogsdriver streaming to your log-aggregation system. - Health check:
command: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:5002/api/health || exit 1"]with a 60s start period. - Architecture: Fargate supports both
X86_64andARM64. ARM64 (Graviton) runs ~20% cheaper, use it if you don't have a hard amd64 dependency. The shipped image is multi-arch.
Migrations on ECS
Set MIGRATE_ON_BOOT=false on the service and gate the schema change with a one-shot task: a separate task definition on the same image with the command overridden to node dist/server/database/migrate.js. In the pipeline, aws ecs run-task, poll to a successful STOPPED exit (code 0), then update the service. This avoids the multi-task migration race and stops the deploy if the migration fails.
ALB configuration
- Two target groups: one for port 5002 (API), one for port 3000 (UI). Both targets are the ECS service.
- Listener rule: forward
/api/*to the API target group, default forward to the UI target group. - ACM cert on HTTPS listener.
- Target group health check:
/api/healthon port 5002, healthy threshold 2, unhealthy threshold 3, interval 30s, timeout 10s.
RDS for the metadata database
db.t3.smallMulti-AZ is plenty for most teams; scale up only if you have thousands of scripts.- Place the RDS instance in the same VPC as the ECS cluster, in private subnets, with a security group that only accepts 5432 from the ECS task SG.
- Enable automated backups (default 7 days), and turn on Performance Insights for query-level visibility.
- SSL: set
sslmode=requirein the connection string by appending?sslmode=requiretoDB_DEVOPS_DB_HOST, or setPGSSLMODE=requireas an env var on the task.
Updating the service
# Mirror the new tag into your registry
docker pull simchasolutions/db-studio:1.0.2
docker tag simchasolutions/db-studio:1.0.2 <ACCOUNT>.dkr.ecr.us-east-1.amazonaws.com/simcha-db-studio:1.0.2
docker push <ACCOUNT>.dkr.ecr.us-east-1.amazonaws.com/simcha-db-studio:1.0.2
# Run the migration task and wait
aws ecs run-task --task-definition simcha-db-studio-migrate:<rev> ...
# Update the app service to the new task definition revision
aws ecs update-service \\
--cluster <cluster> --service simcha-db-studio \\
--task-definition simcha-db-studio:<new-rev> \\
--force-new-deployment
Rolling deploys with maximumPercent: 200 / minimumHealthyPercent: 100 give zero-downtime updates.