Learn how to install n8n on Docker with step-by-step instructions for Docker run, Docker Compose, PostgreSQL setup, reverse proxy, security, updates, and advanced configurations.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
To install n8n on Docker, you need to pull the n8n Docker image and then run it in a container with the appropriate configurations. This can be done using a simple Docker run command or by creating a Docker Compose file for more customized setups. The process involves setting up environment variables, configuring persistence for your workflows, and potentially setting up a reverse proxy if you need to expose n8n to the internet.
Step 1: Prerequisites
Before installing n8n on Docker, ensure you have the following prerequisites installed:
To check if Docker is installed correctly, run:
docker --version
If you plan to use Docker Compose, check its installation with:
docker-compose --version
Step 2: Simple Installation with Docker Run
The quickest way to get n8n running is using a Docker run command. This approach is good for testing or simple deployments.
docker run -it --rm \\
--name n8n \\
-p 5678:5678 \\
-v ~/.n8n:/home/node/.n8n \\
n8nio/n8n
This command:
After running this command, you can access n8n by opening a browser and navigating to:
http://localhost:5678
Step 3: Installation with Docker Compose (Recommended)
For a more production-ready setup, it's better to use Docker Compose. This method allows for easier management and configuration of your n8n instance.
First, create a directory for your n8n installation:
mkdir n8n
cd n8n
Create a docker-compose.yml file in this directory:
nano docker-compose.yml
Add the following content to the file:
version: '3'
services:
n8n:
image: n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH\_ACTIVE=true
- N8N_BASIC_AUTH\_USER=user
- N8N_BASIC_AUTH\_PASSWORD=password
- N8N\_HOST=localhost
- N8N\_PORT=5678
- N8N\_PROTOCOL=http
- NODE\_ENV=production
- WEBHOOK\_URL=https://your-domain.com/
volumes:
- ./n8n\_data:/home/node/.n8n
Save and close the file.
This configuration:
Start n8n with Docker Compose:
docker-compose up -d
The -d
flag runs the container in detached mode (in the background).
To check the logs:
docker-compose logs -f
Step 4: Configure PostgreSQL Database (Optional but Recommended)
By default, n8n uses SQLite for data storage, which is fine for testing but not ideal for production. For a more robust setup, configure n8n to use PostgreSQL.
Update your docker-compose.yml file:
version: '3'
services:
n8n:
image: n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH\_ACTIVE=true
- N8N_BASIC_AUTH\_USER=user
- N8N_BASIC_AUTH\_PASSWORD=password
- N8N\_HOST=localhost
- N8N\_PORT=5678
- N8N\_PROTOCOL=http
- NODE\_ENV=production
- WEBHOOK\_URL=https://your-domain.com/
- DB\_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n
volumes:
- ./n8n\_data:/home/node/.n8n
depends\_on:
- postgres
postgres:
image: postgres:13
restart: always
environment:
- POSTGRES\_USER=n8n
- POSTGRES\_PASSWORD=n8n
- POSTGRES\_DB=n8n
- POSTGRES_NON_ROOT_USER=n8n_non\_root
- POSTGRES_NON_ROOT_PASSWORD=n8n_non\_root
volumes:
- postgres\_data:/var/lib/postgresql/data
volumes:
postgres\_data:
After updating the file, restart your containers:
docker-compose down
docker-compose up -d
Step 5: Setting Up with Traefik Reverse Proxy (Optional)
If you want to expose n8n to the internet with SSL, you can use Traefik as a reverse proxy.
Create a more comprehensive docker-compose.yml file:
version: '3'
services:
traefik:
image: traefik:v2.5
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/acme.json:/acme.json
- ./traefik/traefik.yml:/traefik.yml
networks:
- web
n8n:
image: n8nio/n8n
restart: always
environment:
- N8N_BASIC_AUTH\_ACTIVE=true
- N8N_BASIC_AUTH\_USER=user
- N8N_BASIC_AUTH\_PASSWORD=password
- N8N\_HOST=n8n.your-domain.com
- N8N\_PORT=5678
- N8N\_PROTOCOL=https
- NODE\_ENV=production
- WEBHOOK\_URL=https://n8n.your-domain.com/
- DB\_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n
volumes:
- ./n8n\_data:/home/node/.n8n
depends\_on:
- postgres
networks:
- web
- internal
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`n8n.your-domain.com`)"
- "traefik.http.routers.n8n.entrypoints=websecure"
- "traefik.http.routers.n8n.tls.certresolver=myresolver"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
postgres:
image: postgres:13
restart: always
environment:
- POSTGRES\_USER=n8n
- POSTGRES\_PASSWORD=n8n
- POSTGRES\_DB=n8n
volumes:
- postgres\_data:/var/lib/postgresql/data
networks:
- internal
networks:
web:
external: true
internal:
external: false
volumes:
postgres\_data:
Create the traefik.yml file:
mkdir -p traefik
nano traefik/traefik.yml
Add the following content:
api:
dashboard: false
entryPoints:
web:
address: ":80"
http:
redirections:
entryPoint:
to: websecure
scheme: https
websecure:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
myresolver:
acme:
email: [email protected]
storage: acme.json
httpChallenge:
entryPoint: web
Create an empty acme.json file and set proper permissions:
touch traefik/acme.json
chmod 600 traefik/acme.json
Create the external network for Traefik:
docker network create web
Start the entire stack:
docker-compose up -d
Remember to replace:
Step 6: Securing Your n8n Installation
For better security, consider these additional configurations in your docker-compose.yml file:
version: '3'
services:
n8n:
image: n8nio/n8n
restart: always
ports:
- "5678:5678"
environment:
# Basic authentication
- N8N_BASIC_AUTH\_ACTIVE=true
- N8N_BASIC_AUTH\_USER=user
- N8N_BASIC_AUTH\_PASSWORD=password
# Encryption key for sensitive data
- N8N_ENCRYPTION_KEY=your-secret-encryption-key
# Limit file size uploads
- N8N_REQUEST_MAX_CONTENT_LENGTH=50mb
# Session timeout (in hours)
- N8N_AUTH_JWT_EXPIRES_IN=24h
# Other standard configurations
- N8N\_HOST=localhost
- N8N\_PORT=5678
- N8N\_PROTOCOL=http
- NODE\_ENV=production
volumes:
- ./n8n\_data:/home/node/.n8n
Replace 'your-secret-encryption-key' with a strong, random string.
Step 7: Updating n8n
To update n8n to the latest version:
docker-compose pull
docker-compose down
docker-compose up -d
If you want to update to a specific version:
docker-compose pull n8nio/n8n:0.193.0 # Replace with the version you want
docker-compose down
docker-compose up -d
Step 8: Monitoring and Maintenance
To view logs:
docker-compose logs -f n8n
To restart n8n:
docker-compose restart n8n
To check n8n container status:
docker-compose ps
For backing up your data, you can either:
tar -zcvf n8n_backup.tar.gz ./n8n_data
Step 9: Troubleshooting Common Issues
Issue 1: Container fails to start
Check the logs:
docker-compose logs n8n
Issue 2: Database connection errors
If you're using PostgreSQL and having connection issues:
docker-compose exec postgres psql -U n8n -c "SELECT 1;"
This tests if the database is working correctly.
Issue 3: Webhook URL not working
Ensure your WEBHOOK_URL is correctly set in the environment variables and that your domain points to your server.
Issue 4: Permission issues with volumes
If you're experiencing permission issues with the mounted volumes:
sudo chown -R 1000:1000 ./n8n\_data
Step 10: Advanced Configurations
Setting up Queue Mode
For handling larger workloads, you can set up n8n with a Redis queue:
version: '3'
services:
n8n:
image: n8nio/n8n
restart: always
environment:
- N8N_BASIC_AUTH\_ACTIVE=true
- N8N_BASIC_AUTH\_USER=user
- N8N_BASIC_AUTH\_PASSWORD=password
- N8N\_HOST=localhost
- N8N\_PORT=5678
- N8N\_PROTOCOL=http
- NODE\_ENV=production
- EXECUTIONS\_MODE=queue
- QUEUE_BULL_REDIS\_HOST=redis
- QUEUE_BULL_REDIS\_PORT=6379
ports:
- "5678:5678"
volumes:
- ./n8n\_data:/home/node/.n8n
depends\_on:
- redis
- postgres
n8n-worker:
image: n8nio/n8n
restart: always
command: worker
environment:
- DB\_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=n8n
- EXECUTIONS\_MODE=queue
- QUEUE_BULL_REDIS\_HOST=redis
- QUEUE_BULL_REDIS\_PORT=6379
volumes:
- ./n8n\_data:/home/node/.n8n
depends\_on:
- redis
- postgres
postgres:
image: postgres:13
restart: always
environment:
- POSTGRES\_USER=n8n
- POSTGRES\_PASSWORD=n8n
- POSTGRES\_DB=n8n
volumes:
- postgres\_data:/var/lib/postgresql/data
redis:
image: redis:6-alpine
restart: always
volumes:
- redis\_data:/data
volumes:
postgres\_data:
redis\_data:
Setting Environment Variables for Specific Nodes
Some n8n nodes require specific environment variables. For example, to configure the Telegram node:
environment:
- TELEGRAM_ACCESS_TOKEN=your-telegram-bot-token
Step 11: Performance Tuning
For better performance, especially in production environments, add these environment variables to your Docker Compose file:
environment:
# Increase memory limit for Node.js
- NODE\_OPTIONS=--max-old-space-size=4096
# Tune PostgreSQL connections
- DB_POSTGRESDB_MAX\_CONNECTIONS=100
# Set execution timeout
- EXECUTIONS\_TIMEOUT=300
# Set process timeout
- EXECUTIONS_PROCESS_TIMEOUT=900
# Limit the number of executions in memory
- EXECUTIONS_DATA_MAX\_AGE=168
Step 12: Running Multiple n8n Instances
For high availability, you can run multiple n8n instances with a load balancer:
version: '3'
services:
traefik:
image: traefik:v2.5
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/traefik.yml:/traefik.yml
- ./traefik/acme.json:/acme.json
networks:
- web
n8n-1:
image: n8nio/n8n
restart: always
environment:
- N8N_BASIC_AUTH\_ACTIVE=true
- N8N_BASIC_AUTH\_USER=user
- N8N_BASIC_AUTH\_PASSWORD=password
- N8N\_HOST=n8n.your-domain.com
- N8N\_PORT=5678
- N8N\_PROTOCOL=https
- NODE\_ENV=production
- DB\_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- EXECUTIONS\_MODE=queue
- QUEUE_BULL_REDIS\_HOST=redis
volumes:
- ./n8n\_data:/home/node/.n8n
networks:
- web
- internal
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`n8n.your-domain.com`)"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
n8n-2:
image: n8nio/n8n
restart: always
environment:
- N8N_BASIC_AUTH\_ACTIVE=true
- N8N_BASIC_AUTH\_USER=user
- N8N_BASIC_AUTH\_PASSWORD=password
- N8N\_HOST=n8n.your-domain.com
- N8N\_PORT=5678
- N8N\_PROTOCOL=https
- NODE\_ENV=production
- DB\_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- EXECUTIONS\_MODE=queue
- QUEUE_BULL_REDIS\_HOST=redis
volumes:
- ./n8n\_data:/home/node/.n8n
networks:
- web
- internal
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`n8n.your-domain.com`)"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
n8n-worker:
image: n8nio/n8n
restart: always
command: worker
environment:
- DB\_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- EXECUTIONS\_MODE=queue
- QUEUE_BULL_REDIS\_HOST=redis
volumes:
- ./n8n\_data:/home/node/.n8n
networks:
- internal
depends\_on:
- redis
- postgres
postgres:
image: postgres:13
restart: always
environment:
- POSTGRES\_USER=n8n
- POSTGRES\_PASSWORD=n8n
- POSTGRES\_DB=n8n
volumes:
- postgres\_data:/var/lib/postgresql/data
networks:
- internal
redis:
image: redis:6-alpine
restart: always
volumes:
- redis\_data:/data
networks:
- internal
networks:
web:
external: true
internal:
external: false
volumes:
postgres\_data:
redis\_data:
Conclusion
You have now learned how to install n8n on Docker using various configurations, from a basic setup to more advanced production-ready deployments. By following these steps, you can have a fully functional n8n instance running in Docker, ready to create and automate workflows.
Remember to:
For more information and advanced configurations, refer to the official n8n documentation at https://docs.n8n.io/hosting/installation/docker/.
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.