Complete Guide to Running n8n on Docker: Setup, Configuration & Best Practices

Learn how to deploy n8n workflow automation platform on Docker with production-ready configurations, security settings, and scaling strategies for business automation.
n8n is a powerful workflow automation platform that can transform your business processes. Running n8n on Docker provides scalability, consistency, and easy deployment. This comprehensive guide covers everything from basic setup to production-ready configurations.
Table of Contents
- Introduction to n8n and Docker
- Prerequisites and System Requirements
- Basic n8n Docker Setup
- Production Docker Compose Configuration
- Environment Variables and Security
- Database Configuration
- SSL/TLS Setup and Domain Configuration
- Scaling and Performance Optimization
- Backup and Monitoring Strategies
- Troubleshooting Common Issues
Introduction to n8n and Docker
n8n (pronounced "nodemation") is an open-source workflow automation tool that allows you to connect different services and automate repetitive tasks. Docker containerization provides:
- Consistent Environment: Same configuration across development and production
- Easy Scaling: Horizontal scaling with multiple containers
- Isolation: Secure separation from host system
- Version Control: Easy rollbacks and updates
Why Use Docker for n8n?
# Benefits of Docker deployment
✅ Rapid deployment and scaling
✅ Environment consistency
✅ Easy backup and migration
✅ Resource isolation
✅ Simplified updatesPrerequisites and System Requirements
System Requirements
# Minimum Requirements
- CPU: 2 cores
- RAM: 4GB
- Storage: 20GB SSD
- OS: Linux/Windows/macOS with Docker support
# Recommended for Production
- CPU: 4+ cores
- RAM: 8GB+
- Storage: 50GB+ SSD
- Load Balancer: Nginx/TraefikRequired Software
# Install Docker and Docker Compose
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io docker-compose
# CentOS/RHEL
sudo yum install docker docker-compose
# Verify installation
docker --version
docker-compose --versionBasic n8n Docker Setup
Quick Start with Docker Run
# Basic n8n container
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
# With custom timezone
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e GENERIC_TIMEZONE="America/New_York" \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8nSimple Docker Compose Setup
# docker-compose.yml
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- GENERIC_TIMEZONE=UTC
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=your_secure_password
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:# Start the service
docker-compose up -d
# Check status
docker-compose ps
# View logs
docker-compose logs -f n8nProduction Docker Compose Configuration
Complete Production Setup
# docker-compose.production.yml
version: '3.8'
services:
# PostgreSQL Database
postgres:
image: postgres:15
container_name: n8n_postgres
restart: unless-stopped
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n_user
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n_network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n_user -d n8n"]
interval: 30s
timeout: 10s
retries: 3
# n8n Application
n8n:
image: n8nio/n8n:latest
container_name: n8n_app
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
# Database Configuration
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n_user
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# n8n Configuration
- N8N_HOST=${N8N_HOST}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=${WEBHOOK_URL}
# Security
- N8N_BASIC_AUTH_ACTIVE=false
- N8N_USER_MANAGEMENT_DISABLED=false
- N8N_JWT_AUTH_ACTIVE=true
- N8N_JWT_AUTH_HEADER=authorization
- N8N_JWT_AUTH_HEADER_VALUE_PREFIX=Bearer
# Performance
- EXECUTIONS_PROCESS=main
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
- N8N_METRICS=true
# Timezone
- GENERIC_TIMEZONE=${TIMEZONE}
volumes:
- n8n_data:/home/node/.n8n
- n8n_files:/files
networks:
- n8n_network
labels:
# Traefik labels for reverse proxy
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`${N8N_HOST}`)"
- "traefik.http.routers.n8n.tls=true"
- "traefik.http.routers.n8n.tls.certresolver=letsencrypt"
# Redis for Queue Management
redis:
image: redis:7-alpine
container_name: n8n_redis
restart: unless-stopped
volumes:
- redis_data:/data
networks:
- n8n_network
command: redis-server --appendonly yes
# Traefik Reverse Proxy
traefik:
image: traefik:v3.0
container_name: n8n_traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik_data:/data
command:
- --api.dashboard=true
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --certificatesresolvers.letsencrypt.acme.tlschallenge=true
- --certificatesresolvers.letsencrypt.acme.email=${EMAIL}
- --certificatesresolvers.letsencrypt.acme.storage=/data/acme.json
networks:
- n8n_network
volumes:
n8n_data:
n8n_files:
postgres_data:
redis_data:
traefik_data:
networks:
n8n_network:
driver: bridgeEnvironment File (.env)
# .env file for production
# Database
POSTGRES_PASSWORD=your_very_secure_password_here
# n8n Configuration
N8N_HOST=n8n.yourdomain.com
WEBHOOK_URL=https://n8n.yourdomain.com/
TIMEZONE=America/New_York
# SSL Certificate
[email protected]
# Security Keys (generate unique values)
N8N_ENCRYPTION_KEY=your_encryption_key_32_chars_long
N8N_USER_MANAGEMENT_JWT_SECRET=jwt_secret_key_hereEnvironment Variables and Security
Essential Security Variables
# Authentication & Security
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=secure_password
# JWT Configuration
N8N_JWT_AUTH_ACTIVE=true
N8N_JWT_AUTH_HEADER=authorization
N8N_JWT_AUTH_HEADER_VALUE_PREFIX=Bearer
# Encryption
N8N_ENCRYPTION_KEY=your_32_character_encryption_key
# User Management
N8N_USER_MANAGEMENT_DISABLED=false
N8N_USER_MANAGEMENT_JWT_SECRET=jwt_secret
# CORS Settings
N8N_CORS_ORIGIN=https://yourdomain.comPerformance Optimization Variables
# Execution Settings
EXECUTIONS_PROCESS=main
EXECUTIONS_TIMEOUT=3600
EXECUTIONS_TIMEOUT_MAX=14400
# Data Retention
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_ON_SUCCESS=all
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168
# Metrics and Monitoring
N8N_METRICS=true
N8N_METRICS_PREFIX=n8n_
# Node.js Performance
NODE_OPTIONS=--max-old-space-size=4096Database Configuration
PostgreSQL Setup
-- Create n8n database and user
CREATE DATABASE n8n;
CREATE USER n8n_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE n8n TO n8n_user;
-- Optimize PostgreSQL for n8n
ALTER SYSTEM SET shared_preload_libraries = 'pg_stat_statements';
ALTER SYSTEM SET max_connections = 200;
ALTER SYSTEM SET shared_buffers = '256MB';
ALTER SYSTEM SET effective_cache_size = '1GB';MySQL Configuration (Alternative)
# MySQL service in docker-compose
mysql:
image: mysql:8.0
container_name: n8n_mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: n8n
MYSQL_USER: n8n_user
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password# n8n MySQL environment variables
DB_TYPE=mysqldb
DB_MYSQLDB_HOST=mysql
DB_MYSQLDB_PORT=3306
DB_MYSQLDB_DATABASE=n8n
DB_MYSQLDB_USER=n8n_user
DB_MYSQLDB_PASSWORD=${MYSQL_PASSWORD}SSL/TLS Setup and Domain Configuration
Nginx Reverse Proxy Configuration
# /etc/nginx/sites-available/n8n
server {
listen 80;
server_name n8n.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.yourdomain.com/privkey.pem;
# SSL Configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
ssl_prefer_server_ciphers off;
# Security Headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
location / {
proxy_pass http://localhost:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}Let's Encrypt SSL Certificate
# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Obtain certificate
sudo certbot --nginx -d n8n.yourdomain.com
# Auto-renewal
sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quietScaling and Performance Optimization
Horizontal Scaling Setup
# docker-compose.scale.yml
version: '3.8'
services:
n8n-main:
image: n8nio/n8n:latest
environment:
- EXECUTIONS_PROCESS=main
- QUEUE_BULL_REDIS_HOST=redis
depends_on:
- redis
- postgres
n8n-worker:
image: n8nio/n8n:latest
command: n8n worker
environment:
- EXECUTIONS_PROCESS=own
- QUEUE_BULL_REDIS_HOST=redis
depends_on:
- redis
- postgres
deploy:
replicas: 3
n8n-webhook:
image: n8nio/n8n:latest
command: n8n webhook
environment:
- EXECUTIONS_PROCESS=own
- QUEUE_BULL_REDIS_HOST=redis
ports:
- "5679:5678"
depends_on:
- redis
- postgresPerformance Monitoring
# Add monitoring services
prometheus:
image: prom/prometheus:latest
container_name: n8n_prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
container_name: n8n_grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafanaBackup and Monitoring Strategies
Database Backup Script
#!/bin/bash
# backup-n8n.sh
# Configuration
BACKUP_DIR="/backups/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
CONTAINER_NAME="n8n_postgres"
# Create backup directory
mkdir -p $BACKUP_DIR
# Database backup
docker exec $CONTAINER_NAME pg_dump -U n8n_user -d n8n | gzip > $BACKUP_DIR/n8n_db_$DATE.sql.gz
# n8n data backup
docker run --rm -v n8n_data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/n8n_data_$DATE.tar.gz -C /data .
# Cleanup old backups (keep last 7 days)
find $BACKUP_DIR -name "*.gz" -mtime +7 -delete
echo "Backup completed: $DATE"Health Check Script
#!/bin/bash
# health-check.sh
# Check n8n container health
if ! docker ps --filter "name=n8n_app" --filter "status=running" | grep -q n8n_app; then
echo "n8n container is not running!"
exit 1
fi
# Check n8n web interface
if ! curl -f http://localhost:5678/healthz > /dev/null 2>&1; then
echo "n8n web interface is not responding!"
exit 1
fi
echo "n8n is healthy"Monitoring with Docker Healthcheck
# Add to n8n service in docker-compose
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5678/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40sTroubleshooting Common Issues
Container Won't Start
# Check logs
docker-compose logs n8n
# Common issues and solutions:
# 1. Permission issues
sudo chown -R 1000:1000 /path/to/n8n/data
# 2. Port conflicts
netstat -tulpn | grep :5678
# Change port in docker-compose.yml
# 3. Memory issues
docker stats
# Increase memory allocationDatabase Connection Issues
# Test database connectivity
docker exec -it n8n_postgres psql -U n8n_user -d n8n -c "SELECT version();"
# Check environment variables
docker exec n8n_app env | grep DB_
# Recreate with correct settings
docker-compose down
docker-compose up -dPerformance Issues
# Monitor resource usage
docker stats n8n_app
# Check execution logs
docker-compose logs -f n8n | grep -i error
# Optimize database
docker exec -it n8n_postgres psql -U n8n_user -d n8n -c "VACUUM ANALYZE;"SSL Certificate Issues
# Check certificate validity
openssl x509 -in /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem -noout -dates
# Renew certificate
sudo certbot renew --dry-run
# Check Nginx configuration
sudo nginx -tConclusion
Running n8n on Docker provides a robust, scalable platform for workflow automation. This guide covered:
- ✅ Basic and production Docker setups
- ✅ Security configurations and best practices
- ✅ Database setup and optimization
- ✅ SSL/TLS configuration
- ✅ Scaling strategies
- ✅ Backup and monitoring solutions
- ✅ Troubleshooting common issues
Next Steps
- Start with basic setup for development
- Implement production configuration for live environments
- Set up monitoring and backups for reliability
- Scale horizontally as your automation needs grow
Key Benefits Achieved
- Reliable deployment with Docker containerization
- Secure configuration with proper authentication
- Scalable architecture for growing automation needs
- Professional monitoring and backup strategies
Ready to automate your business processes with n8n on Docker? Start with our basic setup and gradually implement production features as your needs evolve.
Need help with n8n Docker deployment or want a custom automation solution? Contact our automation experts for professional setup and configuration services.
Written by
TheDBAdmin Team
KEEP LEARNING WITH THEDBADMIN
Turn this guide into a skill you can prove
Keep reading
Related articles
NextGen DBA + AI Engineer Bootcamp
Instructor-led, lab-first training for production DBAs: PostgreSQL, MongoDB, Docker, Kubernetes and AI.
- Live labs on real execution plans
- Backup, PITR & HA in production
- pgvector, RAG & AI for DBAs
🛒 FROM THE SHOP
Building a Production-Style Cluster with Production-Style Cluster with Percona XtraDB Cluster, ProxySQL, and Keepalived
PDF · 35 pages
₹199₹5,00096% off