⚠️ Important Note:
While most of this phase can be done via GUI, you'll need Docker Desktop installed on your computer to build and push images to ECR. This is a one-time setup step.
While most of this phase can be done via GUI, you'll need Docker Desktop installed on your computer to build and push images to ECR. This is a one-time setup step.
Prerequisites
- Phase 1 completed (VPC, Security Groups, ECR)
- Docker Desktop installed on your computer
- Backend code ready in a folder
- All API keys documented (Supabase, Anthropic, etc.)
Step 1: Store Secrets in AWS Secrets Manager
What is Secrets Manager?
AWS Secrets Manager securely stores sensitive information like API keys, database passwords, and tokens. Your application retrieves them at runtime without hardcoding.
AWS Secrets Manager securely stores sensitive information like API keys, database passwords, and tokens. Your application retrieves them at runtime without hardcoding.
1.1
Create Secret for Backend Configuration
Console Navigation
AWS Console
Search "Secrets Manager"
Secrets Manager
Store a new secret
-
1Click "Store a new secret" button
-
2Secret type: Select "Other type of secret"
-
3Key/value pairs: Click "Add row" for each secret
Add these key-value pairs (one row for each):
| Key | Value (Example) |
|---|---|
| SUPABASE_URL | https://your-project.supabase.co |
| SUPABASE_ANON_KEY | your-anon-key-here |
| SUPABASE_SERVICE_ROLE_KEY | your-service-role-key-here |
| ANTHROPIC_API_KEY | sk-ant-your-key-here |
| OPENAI_API_KEY | sk-your-openai-key-here |
| GEMINI_API_KEY | your-gemini-key-here |
| TAVILY_API_KEY | tvly-your-key-here |
| FIRECRAWL_API_KEY | fc-your-key-here |
| DAYTONA_API_KEY | your-daytona-key-here |
| DAYTONA_SERVER_URL | https://app.daytona.io/api |
| DAYTONA_TARGET | us |
| SENTRY_DSN | https://your-sentry-dsn |
| LANGFUSE_PUBLIC_KEY | pk-lf-your-key |
| LANGFUSE_SECRET_KEY | sk-lf-your-key |
| LANGFUSE_HOST | https://cloud.langfuse.com |
| STRIPE_SECRET_KEY | sk_live_your-stripe-key |
| STRIPE_WEBHOOK_SECRET | whsec_your-webhook-secret |
| ENV_MODE | production |
-
4Encryption key: Select "aws/secretsmanager" (default)
-
5Click "Next"
-
6Secret name: helium/backend/production
-
7Description: Helium backend production secrets
-
8Tags: Add Project = helium
-
9Click "Next"
-
10Rotation: Select "Disable automatic rotation" (for now)We'll set this up later in Phase 6
-
11Click "Next" → Review → "Store"
Secret Stored! Copy the Secret ARN - you'll need it when creating ECS task definitions.
Step 2: Create IAM Roles for ECS
Why Two Roles?
Task Role: Permissions your application needs (read secrets, access S3, etc.)
Execution Role: Permissions ECS needs to start your container (pull images, write logs)
Task Role: Permissions your application needs (read secrets, access S3, etc.)
Execution Role: Permissions ECS needs to start your container (pull images, write logs)
2.1
Create ECS Task Role
Console Navigation
AWS Console
Search "IAM"
Roles (left sidebar)
Create role
-
1Trusted entity type: Select "AWS service"
-
2Use case: Select "Elastic Container Service"
-
3Use case detail: Select "Elastic Container Service Task"
-
4Click "Next"
-
5Search and select: SecretsManagerReadWriteThis allows reading secrets from Secrets Manager
-
6Click "Next"
-
7Role name: helium-ecs-task-role
-
8Description: IAM role for ECS tasks to access AWS services
-
9Click "Create role"
2.2
Create ECS Task Execution Role
Console Navigation
IAM
Roles
Create role
-
1Trusted entity: "AWS service"
-
2Use case: "Elastic Container Service"
-
3Use case detail: "Elastic Container Service Task"
-
4Click "Next"
-
5Search and select these policies:✓ AmazonECSTaskExecutionRolePolicy
✓ AmazonEC2ContainerRegistryReadOnly
✓ SecretsManagerReadWrite -
6Click "Next"
-
7Role name: helium-ecs-execution-role
-
8Click "Create role"
Step 3: Create ECS Cluster
What is an ECS Cluster?
An ECS Cluster is a logical grouping of tasks or services. Think of it as a container for your containerized applications.
An ECS Cluster is a logical grouping of tasks or services. Think of it as a container for your containerized applications.
3.1
Create Production Cluster
Console Navigation
AWS Console
Search "ECS"
Elastic Container Service
Clusters (left sidebar)
Create cluster
-
1Cluster name: helium-production-cluster
-
2Infrastructure: Keep "AWS Fargate (serverless)" checked
-
3Monitoring: Check "Use Container Insights"Provides detailed metrics and logs
-
4Tags: Add Project = helium
-
5Click "Create"
Cluster Created! Your ECS cluster is ready to run containerized applications.
Step 4: Build and Push Docker Image to ECR
⚠️ This Step Requires Docker Desktop
You'll need Docker Desktop installed on your computer. Download from: docker.com
You'll need Docker Desktop installed on your computer. Download from: docker.com
4.1
Get ECR Push Commands from Console
AWS Console provides ready-to-use commands for pushing images to ECR.
Console Navigation
ECR
Repositories
helium-backend
View push commands
-
1Click "View push commands" button (top right)
-
2A modal will appear with 4 commandsCopy each command and run in your terminal (one at a time)
-
3Command 1: Authenticate Docker to ECR
-
4Command 2: Build your Docker imageMake sure you're in your backend directory
-
5Command 3: Tag your image
-
6Command 4: Push image to ECRThis may take 5-10 minutes depending on image size
First Time Using Docker?
Open Terminal (Mac/Linux) or PowerShell (Windows), navigate to your backend folder using
cd path/to/backend, then paste and run each command from the ECR push commands modal.
Image Pushed! Go back to ECR console and refresh - you should see your image with the "latest" tag.
Step 5: Create ECS Task Definition
What is a Task Definition?
A task definition is like a blueprint for your container. It specifies which image to use, how much CPU/memory, environment variables, and more.
A task definition is like a blueprint for your container. It specifies which image to use, how much CPU/memory, environment variables, and more.
5.1
Create Backend Task Definition
Console Navigation
ECS
Task definitions (left sidebar)
Create new task definition
-
1Task definition family: helium-backend
-
2Launch type: Select "AWS Fargate"
-
3Operating system: Linux/X86_64Or select Linux/ARM64 for Graviton3 (recommended for cost savings)
-
4Task size - CPU: 2 vCPU
-
5Task size - Memory: 4 GB
-
6Task role: Select helium-ecs-task-role
-
7Task execution role: Select helium-ecs-execution-role
💡 2025 Tip: Use Graviton3!
If you select ARM64 architecture, you'll get 25-30% better performance and 40% lower costs. Just make sure your Docker image is built for ARM64.
If you select ARM64 architecture, you'll get 25-30% better performance and 40% lower costs. Just make sure your Docker image is built for ARM64.
5.2
Configure Container
Now let's configure the container details within the task definition.
-
1Scroll down to "Container - 1" section
-
2Container name: helium-backend
-
3Image URI: Paste your ECR repository URIFormat:
ACCOUNT-ID.dkr.ecr.us-east-1.amazonaws.com/helium-backend:latest -
4Essential container: Check "Yes"
-
5Port mappings: Click "Add port mapping"
-
6Container port: 8000Protocol: TCP, App protocol: HTTP
5.3
Add Environment Variables from Secrets Manager
Link your Secrets Manager secrets to the container.
-
1Scroll to "Environment variables" section
-
2Click "Add environment variable"
-
3For each secret, select type: "ValueFrom"
-
4Key: Enter the environment variable name (e.g., SUPABASE_URL)
-
5Value: Enter the Secrets Manager ARNFormat:
arn:aws:secretsmanager:us-east-1:ACCOUNT-ID:secret:helium/backend/production:SUPABASE_URL:: -
6Repeat for all secrets (18 total from Step 1)
Quick Tip: Finding Secret ARNs
Go to Secrets Manager → Click your secret → Copy the "Secret ARN" → Add
:KEY_NAME:: at the end (e.g., :SUPABASE_URL::)
5.4
Configure Logging
-
1Scroll to "Log collection" section
-
2Check "Use log collection"
-
3Log driver: Select "awslogs"
-
4Check "Auto-configure CloudWatch Logs"
-
5Log group name: /ecs/helium-backend
5.5
Configure Health Check
-
1Scroll to "Health check" section
-
2Command: CMD-SHELL,curl -f http://localhost:8000/api/health || exit 1
-
3Interval: 30 seconds
-
4Timeout: 5 seconds
-
5Start period: 60 seconds
-
6Retries: 3
-
7Click "Create" at the bottom
Task Definition Created! You now have a blueprint for running your backend container.
Step 6: Create Application Load Balancer
What is an ALB?
An Application Load Balancer distributes incoming traffic across multiple containers, provides SSL termination, and performs health checks.
An Application Load Balancer distributes incoming traffic across multiple containers, provides SSL termination, and performs health checks.
6.1
Request SSL Certificate (Do This First!)
Before creating the ALB, you need an SSL certificate for HTTPS.
Console Navigation
AWS Console
Search "Certificate Manager"
AWS Certificate Manager
Request certificate
-
1Certificate type: Select "Request a public certificate"
-
2Click "Next"
-
3Fully qualified domain name: api.he2.ai
-
4Click "Add another name to this certificate"
-
5Add: *.he2.aiThis covers all subdomains
-
6Validation method: Select "DNS validation"
-
7Key algorithm: RSA 2048
-
8Click "Request"
-
9Click "View certificate"
-
10Under "Domains", click "Create records in Route 53"If your domain is in Route 53, this is automatic. Otherwise, add the CNAME records to your DNS provider.
-
11Wait for status to change to "Issued"This can take 5-30 minutes
⏳ Waiting Period: While the certificate is being validated, you can continue with the next steps. Just don't create the HTTPS listener until the certificate is issued.
6.2
Create Target Group
A target group tells the load balancer where to send traffic.
Console Navigation
AWS Console
Search "EC2"
Target Groups (left sidebar, under Load Balancing)
Create target group
-
1Target type: Select "IP addresses"Required for Fargate tasks
-
2Target group name: helium-backend-tg
-
3Protocol: HTTP
-
4Port: 8000
-
5VPC: Select helium-production-vpc
-
6Protocol version: HTTP1
-
7Health check protocol: HTTP
-
8Health check path: /api/health
-
9Advanced health check settings:• Healthy threshold: 2
• Unhealthy threshold: 3
• Timeout: 5 seconds
• Interval: 30 seconds
• Success codes: 200 -
10Click "Next"
-
11Don't register any targets yet (skip this page)ECS will automatically register tasks
-
12Click "Create target group"
6.3
Create Application Load Balancer
Console Navigation
EC2
Load Balancers (left sidebar)
Create load balancer
-
1Load balancer type: Click "Create" under "Application Load Balancer"
-
2Load balancer name: helium-production-alb
-
3Scheme: Select "Internet-facing"
-
4IP address type: IPv4
-
5VPC: Select helium-production-vpc
-
6Mappings: Check both availability zones✓ us-east-1a → Select helium-production-public-us-east-1a
✓ us-east-1b → Select helium-production-public-us-east-1b -
7Security groups: Select helium-alb-sgRemove the default security group
-
8Listeners: Click "Add listener"
Configure Listeners:
Listener 1 - HTTPS (Port 443):
-
aProtocol: HTTPS
-
bPort: 443
-
cDefault action: "Forward to target group"
-
dTarget group: Select helium-backend-tg
-
eSecure listener settings: Click "Add certificate"
-
fSelect your ACM certificate for api.he2.ai⚠️ Wait until certificate status is "Issued" before this step
Listener 2 - HTTP (Port 80) - Redirect to HTTPS:
-
aClick "Add listener" again
-
bProtocol: HTTP
-
cPort: 80
-
dDefault action: Select "Redirect"
-
eProtocol: HTTPS
-
fPort: 443
-
gStatus code: 301 - Permanently moved
-
9Tags: Add Project = helium
-
10Click "Create load balancer"This takes 2-3 minutes to provision
ALB Created! Copy the DNS name (e.g., helium-production-alb-123456789.us-east-1.elb.amazonaws.com) - you'll need it for DNS configuration.
Step 7: Create ECS Service
What is an ECS Service?
An ECS Service ensures your containers are always running. If a container crashes, the service automatically starts a new one.
An ECS Service ensures your containers are always running. If a container crashes, the service automatically starts a new one.
7.1
Create Backend Service
Console Navigation
ECS
Clusters
helium-production-cluster
Services tab
Create
-
1Compute options: Select "Launch type"
-
2Launch type: FARGATE
-
3Platform version: LATESTThis ensures automatic updates to platform 1.4.0
-
4Task definition: Select helium-backend
-
5Revision: Select "LATEST"
-
6Service name: helium-backend-service
-
7Service type: Replica
-
8Desired tasks: 2Runs 2 containers for high availability
7.2
Configure Networking
-
1Scroll to "Networking" section
-
2VPC: helium-production-vpc (auto-selected)
-
3Subnets: Select both PRIVATE subnets✓ helium-production-private-us-east-1a
✓ helium-production-private-us-east-1b -
4Security group: Select helium-ecs-task-sgRemove the default security group
-
5Public IP: DisabledTasks in private subnets don't need public IPs
7.3
Configure Load Balancing
-
1Scroll to "Load balancing" section
-
2Load balancer type: Select "Application Load Balancer"
-
3Load balancer: Select helium-production-alb
-
4Listener: Select 443:HTTPS
-
5Target group: Select helium-backend-tg
-
6Health check grace period: 60 seconds
7.4
Configure Auto Scaling (Optional but Recommended)
-
1Scroll to "Service auto scaling" section
-
2Check "Use service auto scaling"
-
3Minimum number of tasks: 2
-
4Maximum number of tasks: 10
-
5Scaling policy: Select "Target tracking"
-
6Policy name: cpu-scaling
-
7ECS service metric: ECSServiceAverageCPUUtilization
-
8Target value: 70%
-
9Click "Create"Service creation takes 3-5 minutes
🎉 Service Created! Your backend is now deploying. Watch the "Tasks" tab to see containers starting up.
Step 8: Verify Backend Deployment
8.1
Check Service Status
Console Navigation
ECS
Clusters
helium-production-cluster
Services tab
helium-backend-service
-
1Check "Desired tasks" = 2
-
2Check "Running tasks" = 2Wait 3-5 minutes for tasks to start
-
3Click "Tasks" tab
-
4Verify both tasks show "RUNNING" status
-
5Click on a task ID to view details
-
6Click "Logs" tab to view container logsCheck for any errors in startup
8.2
Test Health Endpoint
Console Navigation
EC2
Load Balancers
helium-production-alb
-
1Copy the "DNS name"
-
2Open browser and visit:
http://YOUR-ALB-DNS/api/healthYou should see a JSON response with status: "healthy"
🎉 Backend is Live! Your FastAPI backend is now running on AWS ECS Fargate with load balancing and auto-scaling!
Phase 2 Verification Checklist
- Secrets stored in Secrets Manager
- ECS task role created
- ECS execution role created
- ECS cluster created
- Docker image built and pushed to ECR
- SSL certificate issued
- Target group created
- Application Load Balancer created
- HTTPS listener configured
- HTTP redirect configured
- ECS service created
- Tasks running (2/2)
- Health endpoint responding
- Auto-scaling configured
- CloudWatch logs working
✅ Phase 2 Complete! Your backend is deployed and running. Ready for Phase 3: Frontend Deployment!