Skip to main content

ECS Staging Setup Guide

Complete step-by-step guide to set up your FishingLog API staging environment on AWS ECS.

📋 Overview

This guide sets up staging infrastructure:

  • ECR Repository (Docker image storage)
  • RDS PostgreSQL (database)
  • ElastiCache Valkey (caching - optional)
  • Application Load Balancer (traffic distribution)
  • Cloudflare (DNS, SSL, CDN - free!)
  • S3 Bucket (images/media)
  • Security Groups (firewall rules)
  • IAM Roles (permissions)
  • ECS Cluster (container orchestration)
  • CloudWatch (monitoring & logs)

Endpoint: api-staging.reelog.app


🎯 Architecture

Users → Cloudflare (DNS/SSL/CDN) → Load Balancer → ECS Containers → RDS PostgreSQL
↓ ↓
S3 (Images) Valkey (Cache)

📦 Prerequisites

  • ✅ AWS Account (console access)
  • ✅ Docker installed (for building/pushing images)
  • ✅ Domain registered (reelog.app)
  • ✅ AWS Cognito User Pool (us-east-2_TZtGx1T3X)
  • ✅ ECS Service-Linked Role (AWSServiceRoleForECS)

Region: us-east-2 (Ohio) - Keep everything in same region


🏷️ Standard Tags

Apply these tags to all resources:

  • Environment = Staging
  • Project = Reelog
  • Purpose = Resource type (e.g., LoadBalancer, Database, Cache)
  • Name = Resource name (e.g., reelog-lb-staging)

🚀 Step 1: Create ECR Repository

  1. ECR ConsoleRepositoriesCreate repository
  2. Settings:
    • Visibility: Private
    • Name: reelog-api-staging
    • Tag immutability: Enabled
    • Image scanning: Leave unchecked (deprecated)
    • Encryption: Default (AWS managed)
  3. Create repository
  4. Copy Repository URI: 606532921651.dkr.ecr.us-east-2.amazonaws.com/reelog-api-staging

Tags:

  • Environment = Staging
  • Project = Reelog
  • Purpose = ECR
  • Name = reelog-api-staging

🗄️ Step 2: Create RDS PostgreSQL Database

  1. RDS ConsoleDatabasesCreate database

Configuration:

  • Creation method: Easy create
  • Engine: PostgreSQL (not Aurora)
  • Version: PostgreSQL 16.x
  • Template: Free tier
  • DB instance identifier: reelog-db-staging
  • Master username: fishinglog_admin
  • Master password: Auto-generate or set your own (⚠️ SAVE IT!)
  • DB instance class: db.t3.micro (Free tier)
  • Storage: 20 GB (Free tier)
  • VPC: vpc-0e0ba14210312bf06
  • Public access: Yes (for staging)
  • VPC security group: Create new reelog-db-sg-staging
  • Deletion protection: Disabled (for staging)

After creation (5-10 minutes):

  1. Copy Endpoint: reelog-db-staging.xxxxx.us-east-2.rds.amazonaws.com
  2. Create database (if not created):
    psql -h reelog-db-staging.xxxxx.us-east-2.rds.amazonaws.com \
    -U fishinglog_admin \
    -d postgres
    Then: CREATE DATABASE fishinglog_db;

Tags:

  • Environment = Staging
  • Project = Reelog
  • Purpose = Database
  • Name = reelog-db-staging

🔴 Step 3: Create ElastiCache Valkey Cache (Optional)

Skip for now if you want to get API running first.

  1. ElastiCache ConsoleValkey cachesCreate Valkey cache

Configuration:

  • Deployment option: Node-based cluster (for free tier)
  • Creation method: Easy create
  • Configuration: Demo (cache.t4g.micro - free tier eligible)
  • Name: reelog-valkey-staging
  • Network type: IPv4
  • Subnet group: Create new reelog-valkey-subnet-staging
    • VPC: vpc-0e0ba14210312bf06
    • Subnets: Select 3 subnets (different AZs)
  • Security group: Will update after creation

After creation (5-10 minutes):

  1. Copy Primary endpoint: reelog-valkey-staging.xxxxx.cache.amazonaws.com:6379
    • ⚠️ Use Primary endpoint (not Configuration endpoint) for single-node setup

Update Security Group:

  1. EC2 ConsoleSecurity Groups → Find Valkey security group
  2. Copy to new security group: reelog-valkey-sg-staging
  3. Edit inbound rules:
    • Remove "All traffic" rule
    • Add: Port 6379, Source: reelog-api-sg-staging security group
  4. Outbound: Leave default (all traffic)
  5. Update Valkey cache to use new security group

Tags:

  • Environment = Staging
  • Project = Reelog
  • Purpose = Cache
  • Name = reelog-valkey-staging

🔒 Step 4: Create Security Groups

Order matters - create in this order:

4.1 Load Balancer Security Group

  1. EC2 ConsoleSecurity GroupsCreate security group
  2. Name: reelog-lb-sg-staging
  3. Description: Security group for Application Load Balancer - Staging
  4. VPC: vpc-0e0ba14210312bf06
  5. Inbound rules:
    • HTTP (80) from 0.0.0.0/0
    • HTTPS (443) from 0.0.0.0/0
  6. Outbound: Default (all traffic)
  7. Tags: Environment=Staging, Project=Reelog, Purpose=LoadBalancer, Name=reelog-lb-sg-staging

4.2 API Security Group

  1. Create security group
  2. Name: reelog-api-sg-staging
  3. Description: Security group for ECS API containers - Staging
  4. VPC: vpc-0e0ba14210312bf06
  5. Inbound rules:
    • HTTP (80) from reelog-lb-sg-staging security group
    • HTTPS (443) from reelog-lb-sg-staging security group
  6. Outbound: Default (all traffic)
  7. Tags: Environment=Staging, Project=Reelog, Purpose=API, Name=reelog-api-sg-staging

Save Security Group ID: sg-08d7ea63ef8d6091e (you'll need this)

4.3 Database Security Group

  1. Create security group
  2. Name: reelog-db-sg-staging
  3. Description: Security group for RDS database - Staging
  4. VPC: vpc-0e0ba14210312bf06
  5. Inbound rules:
    • PostgreSQL (5432) from reelog-api-sg-staging security group
  6. Outbound: Default (all traffic)
  7. Tags: Environment=Staging, Project=Reelog, Purpose=Database, Name=reelog-db-sg-staging

⚖️ Step 5: Create Application Load Balancer

5.1 Create Target Group

  1. EC2 ConsoleTarget GroupsCreate target group
  2. Configuration:
    • Target type: IP addresses
    • Name: reelog-api-tg-staging
    • Protocol: HTTP
    • Port: 80
    • IP address type: IPv4
    • VPC: vpc-0e0ba14210312bf06
    • Protocol version: HTTP1
    • Health check: HTTP, Path: /health, Success codes: 200
      • Uses /health endpoint which doesn't require authentication (for load balancer health checks)
      • The /ping endpoint requires authentication and is for authenticated API health checks
    • Advanced: Healthy threshold: 2, Unhealthy: 3, Interval: 30s
  3. Tags: Environment=Staging, Project=Reelog, Purpose=TargetGroup, Name=reelog-api-tg-staging
  4. Create target group

5.2 Request ACM Certificate

  1. Certificate Manager (ACM)Request certificate
  2. Certificate type: Public certificate
  3. Domain: api-staging.reelog.app
  4. Validation: DNS validation
  5. Request
  6. Copy DNS validation record (Name and Value)
  7. Add to Cloudflare DNS (Step 13.1) - DNS only (gray cloud)
  8. Wait 5-10 minutes for validation → Status: "Issued"

5.3 Create Load Balancer

  1. EC2 ConsoleLoad BalancersCreate Load Balancer
  2. Type: Application Load Balancer
  3. Name: reelog-lb-staging
  4. Scheme: Internet-facing
  5. IP address type: IPv4
  6. Network mapping:
    • VPC: vpc-0e0ba14210312bf06
    • Subnets: Select at least 2 AZs
  7. Security groups: reelog-lb-sg-staging

Listeners:

HTTP (Port 80):

  • Action: Redirect to HTTPS (301)

HTTPS (Port 443):

  • Action: Forward to reelog-api-tg-staging
  • SSL certificate: From ACM → api-staging.reelog.app
  • Pre-routing: No pre-routing action
  • Target group: reelog-api-tg-staging, Weight: 1
  • Stickiness: Off
  • Listener tags: Environment=Staging, Project=Reelog, Protocol=HTTPS, Port=443

Load Balancer tags:

  • Environment=Staging, Project=Reelog, Purpose=LoadBalancer, Name=reelog-lb-staging

After creation:

  • Copy DNS name: reelog-lb-staging-809655828.us-east-2.elb.amazonaws.com

🏗️ Step 6: Create ECS Cluster

⚠️ Prerequisite: Check ECS Service-Linked Role

  1. IAM ConsoleRoles → Search AWSServiceRoleForECS
  2. If NOT found, create it:
    • IAMRolesCreate role
    • Trusted entity: AWS service → Elastic Container Service
    • Select: Elastic Container Service (service-linked role)
    • Create role

6.1 Create Cluster

  1. ECS ConsoleClustersCreate cluster
  2. Configuration:
    • Name: reelog-staging
    • Service Connect: Leave blank
    • Infrastructure: Fargate only
    • Container Insights: Turned off (for staging)
    • ECS Exec: None
    • Encryption: Default AWS managed keys
  3. Tags: Environment=Staging, Project=Reelog, Purpose=ECSCluster, Name=reelog-staging
  4. Create

🔐 Step 7: Create IAM Roles

7.1 Task Execution Role

  1. IAM ConsoleRolesCreate role
  2. Trusted entity type: Select AWS service
  3. Use case: Select Elastic Container Service
    • You'll see: "Allow an AWS service like EC2, Lambda, or others to perform actions in this account"
    • Scroll down to find "Elastic Container Service"
  4. Select: Elastic Container Service Task
    • This is the specific use case for ECS tasks
  5. Click "Next"
  6. Add permissions:
    • Search and select: AmazonECSTaskExecutionRolePolicy
    • Search and select: AmazonEC2ContainerRegistryReadOnly
  7. Click "Next"
  8. Role name: reelog-ecs-task-execution-role
  9. Description: Execution role for ECS tasks - allows ECR access and CloudWatch logging
  10. Tags (optional but recommended):
    • Tag 1: Key=Environment, Value=Staging
    • Tag 2: Key=Project, Value=Reelog
    • Tag 3: Key=Purpose, Value=TaskExecutionRole
    • Tag 4: Key=Name, Value=reelog-ecs-task-execution-role
  11. Click "Create role"
  12. After creation, click on the role → Add permissionsCreate inline policy:
    • JSON tab → Paste:
    {
    "Version": "2012-10-17",
    "Statement": [{
    "Effect": "Allow",
    "Action": [
    "logs:CreateLogGroup",
    "logs:CreateLogStream",
    "logs:PutLogEvents"
    ],
    "Resource": "arn:aws:logs:us-east-2:*:*"
    }]
    }
    • Policy name: CloudWatchLogsPolicy
    • Create policy

7.2 Task Role

  1. IAM ConsoleRolesCreate role
  2. Trusted entity type: Select AWS service
  3. Use case: Select Elastic Container Service
  4. Select: Elastic Container Service Task
  5. Click "Next"
  6. Add permissions:
    • Search and select: AmazonS3FullAccess
    • Or create custom policy for specific bucket access (more secure)
  7. Click "Next"
  8. Role name: reelog-ecs-task-role
  9. Description: Task role for ECS containers - allows S3 access
  10. Tags (optional but recommended):
    • Tag 1: Key=Environment, Value=Staging
    • Tag 2: Key=Project, Value=Reelog
    • Tag 3: Key=Purpose, Value=TaskRole
    • Tag 4: Key=Name, Value=reelog-ecs-task-role
  11. Click "Create role"

📦 Step 8: Create ECS Task Definition

  1. ECS ConsoleTask DefinitionsCreate new task definition
  2. Task definition family: reelog-api-staging
    • Family name groups different revisions of the same task definition
    • Must be 1-255 characters, valid: a-z, A-Z, 0-9, hyphens (-), underscores (_)
  3. Launch type: Fargate
  4. Task size: 0.5 vCPU, 1 GB memory
  5. Task execution role: reelog-ecs-task-execution-role
  6. Task role: reelog-ecs-task-role
  7. Network mode: awsvpc

Container:

  • Name: reelog-api
  • Image URI: 606532921651.dkr.ecr.us-east-2.amazonaws.com/reelog-api-staging:latest
  • Port mappings: 80 (HTTP)
  • Environment variables:
    • ASPNETCORE_ENVIRONMENT = Staging
    • ASPNETCORE_URLS = http://+:80
      • ⚠️ CRITICAL: Makes the app listen on port 80 (required for load balancer)
      • Without this, ASP.NET Core defaults to port 8080 in containers
    • ConnectionStrings__DefaultConnection = Host=reelog-db-staging.cn0muq2ok0qq.us-east-2.rds.amazonaws.com;Port=5432;Database=fishinglog_db;Username=fishinglog_admin;Password=YOUR_PASSWORD
    • Redis__ConnectionString = reelog-valkey-staging.oe3wvy.cache.amazonaws.com:6379 (if using Valkey)
  • Logging: awslogs
    • Log driver: awslogs
    • Log group: /ecs/reelog-api-staging
    • Region: us-east-2
    • Stream prefix: ecs
    • awslogs-create-group: ✅ Keep enabled (recommended)
      • Automatically creates CloudWatch log group if it doesn't exist
      • Safety net - even though we created it manually in Step 11
      • Harmless if log group already exists
      • Prevents errors if log group is accidentally deleted

Tags (optional but recommended):

  • Tag 1: Key=Environment, Value=Staging
  • Tag 2: Key=Project, Value=Reelog
  • Tag 3: Key=Purpose, Value=TaskDefinition
  • Tag 4: Key=Name, Value=reelog-api-staging

Create


🚀 Step 9: Create ECS Service

  1. ECS ConsoleClustersreelog-stagingServicesCreate
  2. Configuration:
    • Task definition: reelog-api-staging:1
    • Service name: reelog-api-staging

Compute configuration - advanced:

Compute options:

  • Select: Launch type ✅ RECOMMENDED
    • Simpler - Direct launch without capacity provider strategy
    • Standard approach - Works well for most use cases
    • Easier to manage - No need to configure capacity providers

Launch type:

  • Select: Fargate
    • Serverless containers - no EC2 instances to manage
    • Auto-scaling handled by AWS

Alternative: Capacity provider strategy (Advanced - Not needed):

  • ⚠️ Use custom - Only if you need advanced task distribution
  • ⚠️ More complex - Requires configuring capacity providers
  • ⚠️ Use cluster default - Only if cluster has default capacity provider strategy configured
  • For staging, use Launch type - Simpler and sufficient

Troubleshooting configuration - recommended:

Turn on ECS Exec:

  • Enable ECS Exec: ✅ Enable (recommended for staging)
    • Useful for debugging - Run interactive commands in containers
    • Helpful for troubleshooting - Inspect container state, check logs, test connections
    • Safe for staging - Can help diagnose issues quickly

What is ECS Exec?

  • Allows you to run interactive commands in running containers
  • Similar to docker exec but for ECS containers
  • Useful for debugging, checking environment variables, testing database connections
  • Requires task role with appropriate permissions (already configured)

When to use:

  • Staging: Enable - Useful for debugging and troubleshooting
  • ⚠️ Production: Consider enabling for troubleshooting, but be mindful of security
  • Use cases: Check logs, test database connections, inspect environment variables, debug issues

Note: ECS Exec can only be enabled when launching new tasks, not for existing ones. If you need it later, you'll need to update the service.

Continue with:

  • Number of tasks: 2
    • VPC: vpc-0e0ba14210312bf06
    • Subnets: Select at least 2 subnets
    • Security groups: reelog-api-sg-staging
    • Load balancer: Application Load Balancer
      • Load balancer: Select reelog-lb-staging
      • Listener: Select HTTPS:443 (or HTTP:80 if you only have HTTP listener)
        • Select the HTTPS listener (port 443) since we configured HTTPS in Step 5.3
        • This is the listener that forwards traffic to your target group
      • Target group: Select reelog-api-tg-staging
      • Container to load balance:
        • Container name: reelog-api
        • Container port: 80
        • Production listener port: 443 (matches the HTTPS listener)
        • Or it may show as: reelog-api:80:443
    • Service auto scaling - optional: ✅ Enable (recommended)

Auto Scaling Configuration:

Use service auto scaling:

  • Check "Use service auto scaling" to enable automatic scaling

Task limits:

  • Minimum number of tasks: 2
    • Lower boundary - service will never scale below this
    • Ensures high availability (at least 2 tasks)
  • Maximum number of tasks: 10
    • Upper boundary - service will never scale above this
    • Prevents runaway costs

Scaling policy type:

  • Select: Target tracking ✅ RECOMMENDED
    • Simpler - Automatically adjusts based on target metric value
    • Recommended - AWS manages scaling decisions
    • Works well for most applications

Alternative: Step scaling (Advanced - Not needed):

  • ⚠️ More complex - Requires configuring step adjustments and alarms
  • ⚠️ More control - Fine-grained scaling based on alarm breaches
  • ⚠️ Use only if you need custom scaling behavior

Target tracking policy configuration:

Policy name:

  • Name: cpu-memory-scaling (or leave default)
    • Identifies this scaling policy

ECS service metric:

  • Select: ECSServiceAverageCPUUtilization (for CPU-based scaling)
    • Recommended - Scales based on CPU usage
    • Or select ECSServiceAverageMemoryUtilization for memory-based scaling

Target value:

  • CPU target: 70 (percent)
    • Service will scale to maintain ~70% CPU utilization
    • If CPU > 70%, scale out (add tasks)
    • If CPU < 70%, scale in (remove tasks)

Scale-out cooldown period:

  • Value: 60 seconds (default)
    • Wait 60 seconds after scaling out before scaling again
    • Prevents rapid scaling up

Scale-in cooldown period:

  • Value: 300 seconds (5 minutes) - recommended
    • Wait 5 minutes after scaling in before scaling again
    • Longer cooldown prevents rapid scaling down
    • Gives time to verify traffic decrease is sustained

Turn off scale-in:

  • Leave unchecked (allow scale-in)
    • Recommended - Allows service to scale down when not needed
    • Cost-effective - Saves money when traffic is low
    • ⚠️ Check only if you want to prevent scale-in (always keep max tasks)

Optional: Add second scaling policy (Memory):

  • Click "Add another policy" (if available)
  • Policy name: memory-scaling
  • Metric: ECSServiceAverageMemoryUtilization
  • Target value: 80 (percent)
  • Same cooldown periods as CPU policy

Note: You can configure multiple scaling policies (CPU and Memory). The service will scale based on whichever metric requires more tasks.

Tags - optional:

Turn on Amazon ECS managed tags:

  • Enable (recommended)
    • Automatically tags tasks with cluster and service names
    • Helps identify tasks in AWS Cost and Usage Report
    • Useful for cost tracking - See costs per service/cluster
    • No downside - Free and helpful

Propagate tags from:

  • Select: Task definition ✅ RECOMMENDED
    • Automatically propagates tags from task definition to tasks
    • Consistent tagging - Tasks inherit task definition tags
    • Less manual work - Don't need to tag tasks separately
    • Alternative: Service - Propagates service tags to tasks
    • Alternative: Do not propagate - No automatic tag propagation

Service tags:

  • Click "Add tag" and add each of these:
  1. Tag 1:

    • Key: Environment
    • Value: Staging
  2. Tag 2:

    • Key: Project
    • Value: Reelog
  3. Tag 3:

    • Key: Purpose
    • Value: ECSService
  4. Tag 4:

    • Key: Name
    • Value: reelog-api-staging
  5. Tag 5 (Optional):

    • Key: ManagedBy
    • Value: Manual

What happens:

  • Service tags: Applied to the service itself
  • ECS managed tags: Automatically added to tasks (cluster name, service name)
  • Propagated tags: Task definition tags automatically copied to tasks
  • Result: Tasks have comprehensive tags for cost tracking and organization

Create service


🪣 Step 10: Create S3 Bucket

Single bucket with prefixes (recommended for social media apps):

  • One bucket for all content types (users, posts, groups, logs, models)
  • Organize with prefixes (folders) in your application code
  • Simpler management - Single bucket policy, one set of permissions
  • Cost-effective - No per-bucket charges

Bucket Setup:

  1. S3 ConsoleCreate bucket
  2. Bucket type: Select General purpose ✅ RECOMMENDED
    • Multi-AZ redundancy - Data stored across multiple Availability Zones
    • Cost-effective - Standard S3 pricing
    • Works with Cloudflare CDN - CDN handles latency
    • Supports all storage classes - Standard, IA, Glacier, etc.
    • Standard choice for most applications
    • ⚠️ Directory (Express One Zone) - Only for ultra-low latency needs (not needed here)
  3. Name: reelog-content-staging (globally unique)
    • Generic name allows all content types (images, videos, models, etc.)
  4. Region: us-east-2
  5. Block public access: ✅ Keep all settings enabled (we'll configure this after creation)
    • During creation, leave Block Public Access settings ON
    • We'll configure public read access AFTER bucket creation
  6. Versioning: Enable (optional, recommended for staging)
  7. Encryption: SSE-S3

Tags - optional:

  • Click "Add tag" and add each of these:
  1. Tag 1:

    • Key: Environment
    • Value: Staging
  2. Tag 2:

    • Key: Project
    • Value: Reelog
  3. Tag 3:

    • Key: Purpose
    • Value: Storage
  4. Tag 4:

    • Key: Name
    • Value: reelog-content-staging
  5. Tag 5 (Optional):

    • Key: ManagedBy
    • Value: Manual
  6. Create bucket

Configure Block Public Access (required before adding bucket policy):

  1. After bucket creation, go to your bucket → Permissions tab
  2. Block Public Access settingsEdit
  3. Uncheck the following setting:
    • Uncheck: "Block public access to buckets and objects granted through new public bucket or access point policies"
      • This allows the bucket policy to grant public read access
      • Other settings can remain checked for security
  4. Save changes
  5. Confirm by typing confirm in the confirmation dialog

Why this is needed:

  • The bucket policy grants public read access ("Principal": "*")
  • Block Public Access settings prevent public access by default
  • We need to allow public bucket policies to enable public read
  • This is safe because the policy only allows GetObject (read), not write/delete

Add Bucket Policy (for public read):

  1. Still in Permissions tabBucket policyEdit
  2. Paste the following JSON policy:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::reelog-content-staging/*"
}]
}
  1. Save changes
  2. Verify - You should see a warning that the bucket is publicly accessible (this is expected)

What this policy does:

  • Allows public read access (s3:GetObject) to all objects in the bucket
  • Anyone can view/download files via URL
  • Does NOT allow write, delete, or list operations
  • Safe for serving images/media via Cloudflare CDN

Prefix Structure (organized in application code):

reelog-content-staging/
├── users/{userId}/ # User avatars, cover photos, profile photos
├── posts/{postId}/ # Post images/videos
├── groups/{groupId}/ # Group avatars, cover photos
├── logs/{logId}/ # Fishing log photos, catch photos
├── models/ # 3D models (boats, rods, reels)
│ ├── boats/
│ ├── rods/
│ └── reels/
└── temp/ # Temporary uploads (presigned URLs)

Note: Prefix organization happens in your application code when uploading files. The bucket itself is just a container - AWS doesn't enforce folder structure.


📊 Step 11: Create/Update CloudWatch Log Group

Check if log group already exists:

  1. CloudWatch ConsoleLogsLog groups
  2. Search for /ecs/reelog-api-staging

If log group exists (update retention):

  1. Click on /ecs/reelog-api-staging
  2. Configuration tab → Edit retention
  3. Retention period: Select 7 days (or your preferred retention)
    • Current: 1 week (matches recommendation)
  4. Save changes

If log group doesn't exist (create new):

  1. Log groupsCreate log group
  2. Log group name: /ecs/reelog-api-staging
  3. Retention: 7 days
  4. Create

Note: AWS may automatically create log groups when ECS tasks start logging. If it already exists, just update the retention settings.


🌐 Step 12: Configure Cloudflare DNS

12.1 ACM Certificate Validation

  1. ACM Console → Certificate → Copy DNS validation record
  2. CloudflareDNSAdd record
    • Type: CNAME
    • Name: Validation record name from ACM
    • Target: Validation record value from ACM
    • Proxy: ❌ DNS only (gray cloud) - Required!
    • TTL: Auto
    • Comment (optional): ACM Certificate Validation - api-staging.reelog.app
      • Helps identify this record for future reference
  3. Wait 5-10 minutes → Certificate status: "Issued"

12.2 API DNS Record

  1. CloudflareDNSAdd record
    • Type: CNAME
    • Name: api-staging
    • Target: reelog-lb-staging-809655828.us-east-2.elb.amazonaws.com
    • Proxy: ✅ Proxied (orange cloud)
    • TTL: Auto
    • Comment (optional): Staging API - Points to AWS ALB
      • Documents that this routes api-staging.reelog.app to the staging load balancer
  2. Save

12.3 SSL/TLS Settings

  1. CloudflareSSL/TLSOverview
  2. SSL/TLS encryption mode: Full (strict)
    • Requires valid ACM certificate on Load Balancer
    • Provides end-to-end encryption

🐳 Step 13: Build and Push Docker Image

  1. ECR Consolereelog-api-stagingView push commands
  2. Copy login command and run:
    aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 606532921651.dkr.ecr.us-east-2.amazonaws.com
  3. Build image:
    docker build -t reelog-api-staging .
  4. Tag image:
    docker tag reelog-api-staging:latest 606532921651.dkr.ecr.us-east-2.amazonaws.com/reelog-api-staging:latest
  5. Push image:
    docker push 606532921651.dkr.ecr.us-east-2.amazonaws.com/reelog-api-staging:latest

✅ Step 14: Verify Deployment

  1. Test health check (unauthenticated - for load balancer):

    curl https://api-staging.reelog.app/health

    Should return: {"status":"healthy","timestamp":"..."}

    Test authenticated ping (for API monitoring):

    curl -H "Authorization: Bearer YOUR_TOKEN" https://api-staging.reelog.app/ping

    Should return: "pong (secure)"

  2. Check ECS service: Tasks should be running and healthy

  3. Check Load Balancer: Target group should show healthy targets

  4. Check CloudWatch logs: Logs should be appearing


📋 Checklist

  • ECR repository created
  • RDS database created and accessible
  • Valkey cache created (optional)
  • Security groups created (LB, API, DB, Valkey)
  • Load Balancer created
  • Target group created
  • ACM certificate validated
  • ECS cluster created
  • IAM roles created
  • Task definition created
  • ECS service running
  • S3 bucket created
  • CloudWatch log group created
  • Cloudflare DNS configured
  • Docker image pushed
  • API accessible at https://api-staging.reelog.app

💰 Estimated Monthly Costs (Staging)

  • ECS Fargate (2 tasks): ~$15/month
  • RDS db.t3.micro: ~$15/month (or free tier)
  • Valkey cache.t4g.micro: Free tier (750 hours/month) or ~$9.50/month
  • Load Balancer: ~$16/month
  • Cloudflare: FREE
  • S3: ~$1/month
  • Total: ~$47-57/month (or ~$32/month with free tier)

Last Updated: Current Date
Region: us-east-2
Domain: reelog.app