
Cost-Effective Workflow Automation: Deploying n8n on Amazon Lightsail
- Stephen Jones
- Aws
- June 10, 2025
Table of Contents
Recently I’ve been trying out n8n as a workflow automation tool and I’m really enjoying the flexibility it offers. Of course, being an AWS Community Builder I would naturally run this on AWS Fargate as the n8n software is available as a container, however to keep the costs down I ended up running it on Amazon Lightsail.
Here’s why
The above architecture gets expensive very quickly due to a number of reasons.
- Public IPs required on my services to be able to pull from DockerHub
- To remove Public IPs I would need a NAT GW or Private Link so no cost savings
- To be able to use ACM I need to terminate users on an ALB
All the above, while robust and highly scalable if required, its a little overkill for little old me and would cost me about 75$ USD per month.
The n8n cloud service offers a very reasonable pricing of 20 Euros per month if you don’t want the hassle of running your own - N8n Cloud Sign-Up
However, if you just want a personal instance of n8n and are comfortable running it yourself, Amazon Lightsail + this guide = your automation platform running in minutes.
💡
There are features you don’t get if you Self-Host, however it’s a good way to test our the functionality.
Why Lightsail for n8n?
- Fixed, predictable pricing
- Simple setup compared to full AWS EC2
- Managed infrastructure - less overhead
- Perfect resource sizing for self-hosted n8n workloads
Setting Up Your Lightsail Instance
This couldn’t be easier. Choose a size and click, click next. For full details checkout the offical docs. Just make a note of the public IP address and throw this in your DNS zone. I’m using Route 53, but all you need is a simple n8n hostname to IP address lookup for the certificate validation to be established.
Installing Docker
Docker is going to perform the equivalent functions of AWS Fargate for me, so lets get it installed.
sudo yum update -y
sudo amazon-linux-extras install docker
sudo service docker start
sudo usermod -a -G docker ec2-user
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
This will
- Update the installed packages and package cache on your instance
- Install the most recent Docker Community Edition package
- Start the Docker service.
- Add the
ec2-userto the docker group so that you can run Docker commands without using sudo. - Pull down the latest docker-compose binary and enable it in
/usr/local/bin
Setting Up n8n
Create the following docker-compose.yml file:
volumes:
db_storage:
n8n_storage:
le_certs:
networks:
proxy:
name: proxy
internal:
name: n8n_internal
services:
traefik:
image: traefik:v3.0
command:
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=proxy
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --entrypoints.websecure.address=:443
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.le.acme.email=${EMAIL}
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- le_certs:/letsencrypt
networks: [proxy]
restart: unless-stopped
postgres:
image: postgres:16
environment:
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
volumes:
- db_storage:/var/lib/postgresql/data
networks: [internal]
restart: unless-stopped
n8n:
image: docker.n8n.io/n8nio/n8n
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_HOST=${DOMAIN}
- N8N_PROTOCOL=https
- N8N_RUNNERS_ENABLED=true
- WEBHOOK_URL=https://${DOMAIN}/
expose: ["5678"]
volumes:
- n8n_storage:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
labels:
- traefik.enable=true
- traefik.http.routers.n8n.rule=Host(`${DOMAIN}`)
- traefik.http.routers.n8n.entrypoints=websecure
- traefik.http.routers.n8n.tls.certresolver=le
- traefik.http.services.n8n.loadbalancer.server.port=5678
- traefik.docker.network=proxy
- traefik.http.middlewares.websocket-headers.headers.customrequestheaders.Origin=wss://${DOMAIN}
- traefik.http.routers.n8n.middlewares=websocket-headers
networks:
- proxy
- internal
restart: unless-stopped
Let’s break down the key components of this configuration:
Traefik (Reverse Proxy & SSL)
- Handles SSL certificate automation via Let’s Encrypt
- Manages HTTP/HTTPS traffic routing
- Provides secure access to n8n interface
- Runs on the proxy network for external access
PostgreSQL Database
- Provides persistent data storage for n8n
- Runs with configurable credentials
- Includes health monitoring
- Operates on internal network for security
n8n Application
- Configured for PostgreSQL database connection
- Uses secure HTTPS protocol
- Integrates with Traefik for routing
- Connected to both internal and proxy networks for full functionality
Create the environment setting
To populate the variables used above, create a .env file in the same location. This will be injected into the docker-compose on startup.
DOMAIN=n8n.doman.com
EMAIL=user@gmail.com
POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=VeryStrongPassword123
POSTGRES_DB=n8n
POSTGRES_NON_ROOT_USER=n8n_user
POSTGRES_NON_ROOT_PASSWORD=VeryStrongPassword123
Starting n8n
We need to prep the letsencrypt volume with the following command. This only needs to be performed once.
docker run --rm -v le_certs:/letsencrypt alpine sh -c "touch /letsencrypt/acme.json && chmod 600 /letsencrypt/acme.json"
Now lets bring up the container stack
docker-compose up -d
The Traefik container will retrieve a cert from https://letsencrypt.org/ which is validated via the n8n hostname to IP DNS entry added earlier. The n8n container will wait for the database container to be ready via the health check and proceed in starting.
Once up and running you can hit the n8n.domain.com in your browser and start the initial setup which is just to define your logon.
Now you can get into automating things with ease!
Summary
Running n8n on Amazon Lightsail offers a cost-effective alternative to running it on AWS Fargate. While the cloud service costs about 20 euros monthly, Lightsail provides advantages including fixed pricing, simple setup, managed infrastructure, and appropriate resource sizing for self-hosted n8n workloads.
This solution makes it possible to run your own automation platform quickly and efficiently while maintaining security and reliability.
I hope this helps someone else.


