Back to All Guides
Tutorials Published: 2026-02-25· Last Updated: 2026-10-03· By Nawanjana Dilshan
Self-Hosting n8n with Docker Compose: Production Setup Guide
A battle-tested production guide to deploying n8n on Docker Compose with PostgreSQL, automated SSL via Traefik or Caddy, persistent volumes, and queue workers.
Prerequisites & Server Sizing
Running n8n in production requires stability. While SQLite is suitable for testing, a production installation must use PostgreSQL as the backend database to prevent database locking during parallel workflow executions.
- Recommended Server: 2 vCPU, 4GB RAM (e.g. Hetzner CPX21 or DigitalOcean 4GB Droplet, ~$12–$15/mo).
- OS: Ubuntu 24.04 LTS or Debian 12.
- Domain: A pointed DNS A record (e.g.,
n8n.yourdomain.com).
Production docker-compose.yml
Below is the battle-tested Compose configuration featuring PostgreSQL, persistent named volumes, and automated container restarts:
version: '3.8'
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
interval: 5s
timeout: 5s
retries: 10
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
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=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- GENERIC_TIMEZONE=UTC
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
n8n_data:
Essential Production Configurations
- Prune Execution History (
EXECUTIONS_DATA_PRUNE=true): If left unpruned, executions data will quickly bloat your database to tens of gigabytes within months. - Reverse Proxy (Nginx / Caddy): Terminate SSL using Let's Encrypt certificates before forwarding traffic to port
5678. - Automated Backups: Run a nightly cron script creating a compressed
pg_dumpbackup transferred to an off-site S3 bucket.
ND
Written by Nawanjana Dilshan
Freelance n8n, Agentic AI, and Local LLM Specialist based in Sri Lanka. Designing private, production-grade automation systems for businesses in the US, UK, EU, and Australia.