Docker has become the gold standard for deploying applications in consistent, isolated environments, and n8n is no exception. Setting up n8n with Docker offers numerous advantages including easy deployment, consistent environments across different systems, simplified updates, and excellent scalability options. This comprehensive guide will walk you through everything you need to know about running n8n with Docker, from basic setups to production-ready deployments.
Why Choose Docker for n8n?
Docker provides several compelling advantages for n8n deployment:
Consistency and Isolation
Docker ensures n8n runs in a clean, isolated environment regardless of your host system. This eliminates compatibility issues and provides consistent behavior across development, staging, and production environments.
Easy Deployment and Updates
With Docker, deploying n8n is as simple as running a single command. Updates are equally straightforward – just pull the latest image and restart your container.
Scalability
Docker makes it easy to scale n8n horizontally by running multiple instances or implementing queue mode for high-throughput scenarios.
Database Integration
Docker Compose allows you to easily integrate n8n with databases like PostgreSQL, creating a complete automation stack with minimal configuration.
Prerequisites
Before starting, ensure you have:
Docker: Latest version of Docker Desktop (Windows/Mac) or Docker Engine (Linux)
Docker Compose: Included with Docker Desktop or installed separately on Linux
Basic Command Line Knowledge: Familiarity with terminal/command prompt
System Resources: At least 2GB RAM and 10GB free disk space
Installing Docker
Windows and macOS
Download Docker Desktop from the official Docker website and follow the installation instructions.
Linux (Ubuntu/Debian)
Copy code
Remove old Docker versions
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt-get remove $pkg
done
Install prerequisites
sudo apt-get update
sudo apt-get install ca-certificates curl
Add Docker's official GPG key
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
Add Docker repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Verify your installation:
Copy code
docker --version
docker compose version
Method 1: Simple Docker Run (Quick Start)
The fastest way to get n8n running with Docker is using a simple docker run command:
Basic Setup
Copy code
Create a volume for persistent data
docker volume create n8n_data
Run n8n container
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
This command:
Creates a named volume n8n_data for persistent storage
Maps port 5678 from the container to your host
Mounts the volume to preserve your workflows and settings
Uses the official n8n Docker image
Access n8n by opening http://localhost:5678 in your browser.
With Environment Variables
Copy code
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e GENERIC_TIMEZONE="America/New_York" \
-e TZ="America/New_York" \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
With PostgreSQL Database
Copy code
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e DB_TYPE=postgresdb \
-e DB_POSTGRESDB_DATABASE=n8n \
-e DB_POSTGRESDB_HOST=your-postgres-host \
-e DB_POSTGRESDB_PORT=5432 \
-e DB_POSTGRESDB_USER=n8n_user \
-e DB_POSTGRESDB_PASSWORD=your-password \
-e DB_POSTGRESDB_SCHEMA=public \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Method 2: Docker Compose (Recommended)
Docker Compose provides a more manageable way to run n8n, especially when integrating with databases and other services.
Basic Docker Compose Setup
Create a project directory:
Copy code
mkdir n8n-docker
cd n8n-docker
Create a docker-compose.yml file:
Copy code
version: '3.8'
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_HOST=localhost
- N8N_PORT=5678
- N8N_PROTOCOL=http
- NODE_ENV=production
- GENERIC_TIMEZONE=America/New_York
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
volumes:
n8n_data:
Start the services:
Copy code
docker compose up -d
Production-Ready Setup with PostgreSQL
For production environments, use PostgreSQL for better performance and reliability:
Create an .env file:
Copy code
Database Configuration
POSTGRES_DB=n8n
POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=your_secure_password
n8n Configuration
N8N_HOST=your-domain.com
N8N_PORT=5678
N8N_PROTOCOL=https
GENERIC_TIMEZONE=America/New_York
WEBHOOK_URL=https://your-domain.com/
Security
N8N_ENCRYPTION_KEY=your-encryption-key-here
Create a comprehensive docker-compose.yml:
Copy code
version: '3.8'
services:
postgres:
image: postgres:15
restart: always
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
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: docker.n8n.io/n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- DB_POSTGRESDB_SCHEMA=public
- N8N_HOST=${N8N_HOST}
- N8N_PORT=${N8N_PORT}
- N8N_PROTOCOL=${N8N_PROTOCOL}
- NODE_ENV=production
- WEBHOOK_URL=${WEBHOOK_URL}
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
depends_on:
postgres:
condition: service_healthy
volumes:
n8n_data:
postgres_data:
Method 3: Production Setup with SSL/TLS (Traefik)
For production deployments with automatic SSL certificates, use Traefik as a reverse proxy:
Environment Configuration
Create an .env file:
Copy code
Domain Configuration
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
SSL_EMAIL=admin@example.com
Database Configuration
POSTGRES_DB=n8n
POSTGRES_USER=n8n_user
POSTGRES_PASSWORD=your_secure_password
n8n Configuration
GENERIC_TIMEZONE=America/New_York
N8N_ENCRYPTION_KEY=your-encryption-key-here
Complete Production Docker Compose
Copy code
version: '3.8'
services:
traefik:
image: traefik:v3.0
restart: always
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
- "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
- "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- traefik_data:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock:ro
postgres:
image: postgres:15
restart: always
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
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: docker.n8n.io/n8nio/n8n
restart: always
ports:
- "127.0.0.1:5678:5678"
labels:
- traefik.enable=true
- traefik.http.routers.n8n.rule=Host(${SUBDOMAIN}.${DOMAIN_NAME}
)
- traefik.http.routers.n8n.tls=true
- traefik.http.routers.n8n.entrypoints=web,websecure
- traefik.http.routers.n8n.tls.certresolver=mytlschallenge
- traefik.http.middlewares.n8n.headers.SSLRedirect=true
- traefik.http.middlewares.n8n.headers.STSSeconds=315360000
- traefik.http.middlewares.n8n.headers.browserXSSFilter=true
- traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
- traefik.http.middlewares.n8n.headers.forceSTSHeader=true
- traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
- traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
- traefik.http.middlewares.n8n.headers.STSPreload=true
- traefik.http.routers.n8n.middlewares=n8n@docker
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_USER=${POSTGRES_USER}
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- DB_POSTGRESDB_SCHEMA=public
- N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
- GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
depends_on:
postgres:
condition: service_healthy
volumes:
n8n_data:
postgres_data:
traefik_data:
Essential Environment Variables
Core Configuration
Copy code
Basic Settings
N8N_HOST=localhost # Hostname for n8n
N8N_PORT=5678 # Port number
N8N_PROTOCOL=http # Protocol (http/https)
NODE_ENV=production # Environment mode
Timezone
GENERIC_TIMEZONE=America/New_York # Timezone for scheduling
TZ=America/New_York # System timezone
Security
N8N_ENCRYPTION_KEY=your-key-here # Encryption key for credentials
Database Configuration
Copy code
PostgreSQL
DB_TYPE=postgresdb
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_USER=n8n_user
DB_POSTGRESDB_PASSWORD=secure_password
DB_POSTGRESDB_SCHEMA=public
Webhook Configuration
Copy code
WEBHOOK_URL=https://your-domain.com/ # Base URL for webhooks
N8N_PAYLOAD_SIZE_MAX=16 # Max payload size in MB
Performance Settings
Copy code
EXECUTIONS_TIMEOUT=3600 # Execution timeout in seconds
EXECUTIONS_TIMEOUT_MAX=3600 # Maximum execution timeout
N8N_CONCURRENCY_PRODUCTION=10 # Concurrent executions
Security Best Practices
- Use Strong Encryption Keys Generate a secure encryption key:
Copy code
openssl rand -base64 32
- Secure Database Credentials Use strong, unique passwords Consider using Docker secrets for sensitive data Regularly rotate credentials
- Network Security
Copy code
# Restrict database access
postgres:
# ... other config
networks:
- internal
networks:
internal:
driver: bridge
internal: true
- File Permissions Copy code # Create local-files directory with proper permissions mkdir -p local-files chmod 755 local-files
- Regular Updates Copy code # Update to latest version docker compose pull docker compose up -d Advanced Configurations Queue Mode for High Performance For high-throughput scenarios, enable queue mode:
Copy code
services:
redis:
image: redis:7-alpine
restart: always
volumes:
- redis_data:/data
n8n-main:
image: docker.n8n.io/n8nio/n8n
restart: always
environment:
- QUEUE_BULL_REDIS_HOST=redis
- EXECUTIONS_MODE=queue
# ... other config
n8n-worker:
image: docker.n8n.io/n8nio/n8n
restart: always
command: worker
environment:
- QUEUE_BULL_REDIS_HOST=redis
- EXECUTIONS_MODE=queue
# ... other config
volumes:
redis_data:
Custom Node Modules
To add custom npm packages:
Copy code
FROM docker.n8n.io/n8nio/n8n
USER root
RUN npm install -g your-custom-package
USER node
Monitoring and Logging
Copy code
services:
n8n:
# ... other config
environment:
- N8N_LOG_LEVEL=info
- N8N_LOG_OUTPUT=console
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Maintenance and Operations
Backup Strategies
Copy code
Backup volumes
docker run --rm -v n8n_data:/data -v $(pwd):/backup alpine tar czf /backup/n8n-backup.tar.gz /data
Backup database
docker compose exec postgres pg_dump -U n8n_user n8n > backup.sql
Updates and Rollbacks
Copy code
Update to latest version
docker compose pull
docker compose up -d
Rollback to specific version
docker compose down
Edit docker-compose.yml to specify version
docker compose up -d
Monitoring
Copy code
View logs
docker compose logs -f n8n
Monitor resource usage
docker stats
Health checks
docker compose ps
Troubleshooting Common Issues
Container Won't Start
Copy code
Check logs
docker compose logs n8n
Verify environment variables
docker compose config
Check port conflicts
netstat -tulpn | grep 5678
Database Connection Issues
Copy code
Test database connectivity
docker compose exec n8n ping postgres
Check database logs
docker compose logs postgres
Verify credentials
docker compose exec postgres psql -U n8n_user -d n8n
Performance Issues
Increase container memory limits
Optimize database queries
Enable queue mode for high throughput
Monitor resource usage
SSL Certificate Issues
Copy code
Check Traefik logs
docker compose logs traefik
Verify domain DNS
nslookup your-domain.com
Check certificate status
docker compose exec traefik cat /letsencrypt/acme.json
Conclusion
Setting up n8n with Docker provides a robust, scalable, and maintainable automation platform. Whether you're starting with a simple single-container setup or deploying a production-ready system with SSL, databases, and queue processing, Docker offers the flexibility to meet your needs.
The key to success is starting simple and gradually adding complexity as your requirements grow. Begin with the basic Docker Compose setup, then enhance it with PostgreSQL for better performance, add SSL/TLS for security, and implement queue mode for high-throughput scenarios.
Remember to follow security best practices, maintain regular backups, and keep your installation updated. With proper setup and maintenance, your Dockerized n8n instance will provide reliable workflow automation for years to come.
The examples and configurations provided in this guide serve as a solid foundation, but don't hesitate to customize them based on your specific requirements. The n8n community and official documentation are excellent resources for additional guidance and troubleshooting support.
Top comments (0)