Skip to main content

Command Palette

Search for a command to run...

n8n on AWS Fargate with PostgreSQL RDS: Quick Start Guide

Published
9 min read

Prerequisites: AWS account, domain name, basic familiarity with AWS Console
Time to deploy: 45-60 minutes
Monthly cost: ~$20-30 (or ~$10 with Free Tier RDS)

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                     Internet Traffic                        │
│                    (HTTPS Port 443)                         │
└────────────────────────┬────────────────────────────────────┘
                         │
                         ▼
            ┌────────────────────────┐
            │  Application Load      │  ← ACM Certificate
            │  Balancer (ALB)        │    (Free SSL)
            │  Security Group:       │
            │  - Allow 443 from      │
            │    0.0.0.0/0           │
            └────────────┬───────────┘
                         │ HTTP Port 5678
                         ▼
            ┌────────────────────────┐
            │  ECS Fargate           │
            │  (n8n Container)       │  ← Downloads RDS cert
            │  Security Group:       │    on startup
            │  - Allow 5678 from ALB │
            │  - Allow 443 public    │
            └────────┬───────────────┘
                     │ PostgreSQL Port 5432
                     ▼
            ┌────────────────────────┐
            │  RDS PostgreSQL        │
            │  (Persistent Storage)  │
            │  Security Group:       │
            │  - Allow 5432 from ECS │
            └────────────────────────┘

All resources in same VPC

Deployment Flow

Step 1: Create RDS Database (10 mins)

RDS Dashboard → Create Database

Critical settings:

  • Engine: PostgreSQL (latest version)

  • Template: Free tier (or Production)

  • DB identifier: n8n-db

  • Master username: postgres

  • Master password: [generate strong password] ⚠️ Save this

  • Initial database name: n8n ⚠️ Don't skip this

  • Public access: No

  • VPC Security Group: Create new n8n-db-sg

Save: RDS endpoint (e.g., n8n-db.xxx.rds.amazonaws.com)


Step 2: Request SSL Certificate (5 mins)

Certificate Manager → Request Certificate
  • Domain: n8n.yourdomain.com

  • Validation: DNS validation

  • Click Create records in Route 53 (if using Route 53)

  • OR manually add CNAME to your registrar:

      Type: CNAMEHost: _abc123.n8n  (remove .yourdomain.com part)Value: _xyz789.acm-validations.aws
    

Wait: Status changes to Issued (5-30 mins)


Step 3: Create Security Groups (5 mins)

EC2 Dashboard → Security Groups → Create 3 groups

Group 1: ALB Security Group

Name: n8n-alb-sg
Inbound: HTTPS (443) from 0.0.0.0/0

Group 2: ECS Security Group

Name: n8n-ecs-sg
Inbound: 
  - Custom TCP (5678) from n8n-alb-sg
  - HTTPS (443) from 0.0.0.0/0

Group 3: Update Database Security Group

Find: n8n-db-sg (created in Step 1)
Edit Inbound Rules:
  - PostgreSQL (5432) from n8n-ecs-sg

Security flow diagram:

Internet → [443] → ALB (n8n-alb-sg)
              ↓
         [5678 HTTP]
              ↓
          Container (n8n-ecs-sg)
              ↓
          [5432 PostgreSQL]
              ↓
         RDS Database (n8n-db-sg)

Step 4: Create Task Definition (10 mins)

ECS Dashboard → Task Definitions → Create New

Infrastructure:

  • Launch type: AWS Fargate

  • Task size: 1 vCPU, 2 GB

Container:

  • Name: n8n

  • Image: n8nio/n8n:latest

  • Port: 5678

Critical: Docker Configuration:

Entry Point: sh,-c

Command: 
mkdir -p /home/node/certs && wget https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem -O /home/node/certs/rds-ca.pem && /docker-entrypoint.sh

Environment Variables (all required):

KeyValueNotes
DB_TYPEpostgresdb
DB_POSTGRESDB_HOST[RDS endpoint]From Step 1
DB_POSTGRESDB_PORT5432
DB_POSTGRESDB_DATABASEn8n
DB_POSTGRESDB_USERpostgres
DB_POSTGRESDB_PASSWORD[your password]From Step 1
DB_POSTGRESDB_SSL_CA/home/node/certs/rds-ca.pem
DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZEDfalseFixes SSL error
N8N_ENCRYPTION_KEY[random 32-char string]⚠️ Save permanently
WEBHOOK_URLhttps://n8n.yourdomain.com/Your actual domain
GENERIC_TIMEZONEAfrica/LagosYour timezone
TZAfrica/LagosSame as above
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONSfalseSuppress warning

Generate encryption key:

openssl rand -base64 32

Step 5: Create Cluster & Service (15 mins)

ECS → Clusters → Create Cluster

Cluster:

  • Name: n8n-cluster

  • Infrastructure: AWS Fargate

Service (inside cluster):

  • Task Definition: n8n-task (latest revision)

  • Service name: n8n-service

  • Desired tasks: 1

Networking:

  • VPC: Same as RDS

  • Subnets: Select 2+ (different AZs)

  • Security Group: n8n-ecs-sg

  • Public IP: Turn ON ⚠️ (needed for Docker pull)

Load Balancer:

  • Type: Application Load Balancer

  • Name: n8n-alb

  • Listener:

    • Port: 443

    • Protocol: HTTPS

    • Certificate: Select your ACM certificate

  • Target Group:

    • Name: n8n-tg

    • Protocol: HTTP (not HTTPS)

    • Port: 5678 ⚠️ (not 80!)

    • Health check path: /healthz

Service deployment diagram:

┌─────────────────────────────────────────┐
│ 1. ECS launches container               │
│    - Pulls n8nio/n8n:latest            │
│    - Runs startup command               │
│    - Downloads RDS certificate          │
└─────────────┬───────────────────────────┘
              │
              ▼
┌─────────────────────────────────────────┐
│ 2. Container connects to RDS            │
│    - Runs database migrations           │
│    - Initializes n8n                    │
└─────────────┬───────────────────────────┘
              │
              ▼
┌─────────────────────────────────────────┐
│ 3. ALB health checks start              │
│    - Pings /healthz every 30s           │
│    - Waits for 200 OK response          │
└─────────────┬───────────────────────────┘
              │
              ▼
┌─────────────────────────────────────────┐
│ 4. Service status: Active               │
│    - Container status: Running          │
│    - Target status: Healthy             │
└─────────────────────────────────────────┘

Get Load Balancer DNS:

EC2 → Load Balancers → n8n-alb → Copy DNS name
Example: n8n-alb-123456789.us-east-1.elb.amazonaws.com

Step 6: Configure DNS (5 mins)

Add traffic CNAME in your registrar:

Namecheap:

Type: CNAME Record
Host: n8n
Value: n8n-alb-123456789.us-east-1.elb.amazonaws.com
TTL: Automatic

GoDaddy:

Type: CNAME
Name: n8n
Value: [ALB DNS name]
TTL: 600

Cloudflare:

Type: CNAME
Name: n8n
Target: [ALB DNS name]
Proxy: DNS only (grey cloud)

Wait: 5-15 minutes for DNS propagation

Test:

nslookup n8n.yourdomain.com

Step 7: Access n8n (5 mins)

  1. Open browser: https://n8n.yourdomain.com

  2. Create owner account

  3. Start building workflows!

Success checklist:

  • ✅ HTTPS with valid certificate (lock icon)

  • ✅ Can create account (database working)

  • ✅ Webhook URLs show your domain (not localhost)


Verification & Troubleshooting

Check Container Logs

ECS → Clusters → n8n-cluster → Services → n8n-service 
→ Tasks → [click task] → Logs tab

Successful startup:

'/home/node/certs/rds-ca.pem' saved
Initializing n8n process
Starting migration...
Finished migration...
Editor is now accessible via:
http://localhost:5678

Common Issues Flow Chart

Problem: Container crashes immediately
    │
    ├─→ Check logs for "Command sh not found"
    │   └─→ Fix: Entry Point should be "sh,-c"
    │
    ├─→ Check logs for "database does not exist"
    │   └─→ Fix: Recreate RDS with Initial database name = n8n
    │
    ├─→ Check logs for "Connection refused" (port 5432)
    │   └─→ Fix: Edit n8n-db-sg, allow 5432 from n8n-ecs-sg
    │
    └─→ Check logs for "self-signed certificate"
        └─→ Fix: Add DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED=false

Problem: Load Balancer shows "Not reachable"
    │
    └─→ Edit n8n-alb-sg security group
        └─→ Add rule: HTTPS (443) from 0.0.0.0/0

Problem: Target Group shows "Unhealthy"
    │
    ├─→ Check Target Group port = 5678
    │
    ├─→ Check health check path = /healthz
    │
    └─→ Check n8n-ecs-sg allows 5678 from n8n-alb-sg

Problem: Webhooks show "localhost"
    │
    └─→ Add WEBHOOK_URL environment variable
        └─→ Create new Task Definition revision
        └─→ Update Service → Force new deployment

Quick Reference

DNS Records (You Need Both)

Record 1: Certificate Validation (created in Step 2)

Host: _abc123xyz.n8n
Value: _xyz789.acm-validations.aws
Purpose: Keeps SSL certificate valid

Record 2: Traffic Routing (created in Step 6)

Host: n8n
Value: n8n-alb-123456789.us-east-1.elb.amazonaws.com
Purpose: Routes users to your n8n

Security Groups Summary

┌────────────────────────────────────────────┐
│ n8n-alb-sg (Load Balancer)                 │
│ Inbound: 4430.0.0.0/0                   │
└────────────┬───────────────────────────────┘
             │
             ▼
┌────────────────────────────────────────────┐
│ n8n-ecs-sg (Container)                     │
│ Inbound: 5678 ← n8n-alb-sg                 │
│          4430.0.0.0/0                   │
└────────────┬───────────────────────────────┘
             │
             ▼
┌────────────────────────────────────────────┐
│ n8n-db-sg (Database)                       │
│ Inbound: 5432 ← n8n-ecs-sg                 │
└────────────────────────────────────────────┘

Important URLs to Save

Credentials to Save Permanently

  • ⚠️ RDS password: From Step 1

  • ⚠️ N8N_ENCRYPTION_KEY: From Step 4

  • ⚠️ n8n login: Email/password you create


Scaling Quick Guide

Vertical Scaling (More Power)

1. Task Definition → Create new revision
2. Change: 1 vCPU/2GB → 2 vCPU/4GB
3. Service → Update → Select new revision
4. Force new deployment
Cost: Doubles from $36/mo to $72/mo

Horizontal Scaling (More Containers)

1. Service → Update
2. Desired tasks: 13
3. Update
Cost: 3x current container cost

When to scale:

  • CPU consistently >80%

  • Memory consistently >90%

  • Workflows queuing up (delays in execution)

  • Webhooks timing out


Updating n8n Version

# Option 1: Latest (auto-updates)
Task Definition: n8nio/n8n:latest

# Option 2: Pinned version (more control)
Task Definition: n8nio/n8n:1.122.5

To update:
1. Create new Task Definition revision (no changes needed)
2. Update Service → Force new deployment
3. Wait for health checks to pass

Cost Breakdown

┌─────────────────────────────┬──────────────┐
│ Service                     │ Monthly Cost │
├─────────────────────────────┼──────────────┤
│ Fargate (1 vCPU, 2GB)       │ ~$36         │
│ RDS PostgreSQL (db.t3.micro)│ ~$15         │
│ Application Load Balancer   │ ~$22         │
│ Data Transfer               │ ~$5          │
│ CloudWatch Logs             │ ~$3          │
├─────────────────────────────┼──────────────┤
│ TOTAL                       │ ~$81/month   │
│ (With Free Tier RDS)        │ ~$66/month   │
└─────────────────────────────┴──────────────┘

Optimization tips:

  • Use db.t4g.micro instead of db.t3.micro (-20%)

  • Reduce to 0.5 vCPU / 1GB if light usage (-50%)

  • Set CloudWatch log retention to 7 days (-60%)


Post-Deployment Checklist

  • [ ] Test creating a workflow

  • [ ] Test webhook URLs (should show your domain, not localhost)

  • [ ] Set up email notifications (optional)

  • [ ] Create CloudWatch alarm for service down

  • [ ] Test database backup restoration

  • [ ] Document your setup (save credentials, architecture notes)

  • [ ] Set billing alert in AWS ($100 threshold)


Next Steps

Essential (First Week):

  1. Build your first automation workflow

  2. Test webhooks with external service (Stripe, GitHub, etc.)

  3. Monitor CloudWatch logs for errors

  4. Set up at least one alarm (service down)

Recommended (First Month):

  1. Move secrets to AWS Secrets Manager

  2. Set up automated RDS snapshots before major changes

  3. Review costs weekly, right-size resources

  4. Create staging environment (duplicate setup)

Advanced (As You Scale):

  1. Implement worker nodes for high-volume processing

  2. Add CloudFront CDN if serving static content

  3. Use Fargate Spot for non-critical workers (-70% cost)

  4. Set up multi-region deployment for HA


Support Resources

  • n8n Docs: docs.n8n.io

  • n8n Community: community.n8n.io

  • AWS Support: Check service health dashboard

  • Debugging: CloudWatch logs at /ecs/n8n-task


Complete Flow Diagram

┌───────────────────────────────────────────────────────────┐
│                    DEPLOYMENT FLOW                        │
└───────────────────────────────────────────────────────────┘

CREATE INFRASTRUCTURE
    │
    ├─→ [RDS PostgreSQL]
    │   • Database: n8n
    │   • Security: n8n-db-sg
    │   • Endpoint saved
    │
    ├─→ [ACM Certificate]
    │   • Domain: n8n.yourdomain.com
    │   • Validation: DNS CNAME
    │   • Status: Issued ✓
    │
    └─→ [Security Groups]
        • n8n-alb-sg (ALB)
        • n8n-ecs-sg (Container)
        • n8n-db-sg (Database)

CONFIGURE APPLICATION
    │
    ├─→ [Task Definition]
    │   • Image: n8nio/n8n:latest
    │   • Entry Point: sh,-c
    │   • Command: Download RDS cert + start
    │   • Environment: 13 variables
    │
    └─→ [ECS Cluster + Service]
        • Cluster: n8n-cluster
        • Service: n8n-service
        • Launch: Fargate
        • Load Balancer: ALB + Target Group

CONNECT NETWORKING
    │
    └─→ [DNS Configuration]
        • Validation CNAME (for cert)
        • Traffic CNAME (for users)
        • Propagation: 5-15 mins

VERIFY & USE
    │
    ├─→ Container starts
    │   • Downloads certificate
    │   • Connects to RDS
    │   • Runs migrations
    │   • Health check passes
    │
    └─→ Access via browser
        • https://n8n.yourdomain.com
        • Create owner account
        • Build workflows ✓

Deployment time: 45-60 minutes
Difficulty: Intermediate
Production-ready: Yes
Maintenance: Low (managed services)

More from this blog

Software & AI Engineering Blog

12 posts

Teaching deep learning and software engineering from the first principles.