n8n-impl-deployment
Installation
SKILL.md
n8n Deployment & Operations
Quick Reference
| Aspect | Value |
|---|---|
| Docker image | docker.n8n.io/n8nio/n8n |
| Default port | 5678 |
| Data volume | /home/node/.n8n |
| Files volume | /files |
| Default DB | SQLite (use PostgreSQL for production) |
| Queue broker | Redis (BullMQ) |
| Config method | Environment variables (primary) |
Default Ports
| Service | Port |
|---|---|
| n8n | 5678 |
| Redis | 6379 |
| PostgreSQL | 5432 |
| Task Runner Broker | 5679 |
Decision Trees
Which Database?
Need queue mode or multi-instance?
YES -> ALWAYS use PostgreSQL (DB_TYPE=postgresdb)
NO -> Single user / dev environment?
YES -> SQLite is acceptable (default)
NO -> ALWAYS use PostgreSQL for production
Which Deployment Mode?
Expected workflow volume?
Low (< 50 active workflows, single user)
-> Single Docker container, regular mode
Medium (50-200 workflows, team use)
-> Docker Compose with PostgreSQL, regular mode
High (200+ workflows, high webhook traffic)
-> Queue mode: main + workers + Redis + PostgreSQL
Very High (enterprise, HA required)
-> Multi-main + workers + Redis + PostgreSQL + load balancer
Which Backup Strategy?
Database type?
SQLite -> Volume backup (stop container, tar archive)
PostgreSQL -> pg_dump (ALWAYS preferred for production)
ALWAYS also export workflows/credentials via CLI
ALWAYS back up N8N_ENCRYPTION_KEY separately
Critical Rules
- ALWAYS set
N8N_ENCRYPTION_KEYexplicitly in production and back it up. Losing this key means ALL stored credentials become unrecoverable. - ALWAYS share the SAME
N8N_ENCRYPTION_KEYacross ALL instances (main, workers, webhook processors). - ALWAYS use PostgreSQL for queue mode. SQLite does NOT support queue mode.
- ALWAYS set
NODE_ENV=productionfor production deployments. - ALWAYS set
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=truein Docker. - ALWAYS set
N8N_RUNNERS_ENABLED=truefor task runner support. - ALWAYS configure
WEBHOOK_URLwhen behind a reverse proxy. - ALWAYS use the same n8n version across ALL instances in queue mode.
- NEVER use SQLite for multi-instance or queue mode deployments.
- NEVER expose n8n directly to the internet without TLS termination.
- NEVER store
N8N_ENCRYPTION_KEYin version control. - NEVER export credentials with
--decryptedflag in production environments.
Docker Deployment
Basic Docker Run
docker volume create n8n_data
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e GENERIC_TIMEZONE="Europe/Amsterdam" \
-e TZ="Europe/Amsterdam" \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Docker Run with PostgreSQL
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e DB_TYPE=postgresdb \
-e DB_POSTGRESDB_DATABASE=n8n \
-e DB_POSTGRESDB_HOST=postgres-host \
-e DB_POSTGRESDB_PORT=5432 \
-e DB_POSTGRESDB_USER=postgres \
-e DB_POSTGRESDB_PASSWORD=secret \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
Volume Mounts
| Volume | Mount Point | Purpose |
|---|---|---|
n8n_data |
/home/node/.n8n |
SQLite DB, encryption key, settings |
traefik_data |
/letsencrypt |
TLS/SSL certificates (Let's Encrypt) |
./local-files |
/files |
Host directory for workflow file access |
Configuration Methods
- Environment variables (primary):
-e VAR=valueorenvironment:in Compose - Docker Compose file: Variables in
docker-compose.yml _FILEsuffix: Load secrets from files (Docker Secrets, Kubernetes Secrets)- Example:
DB_POSTGRESDB_PASSWORD_FILE=/run/secrets/db_password
- Example:
Updating
docker pull docker.n8n.io/n8nio/n8n # Latest
docker pull docker.n8n.io/n8nio/n8n:1.81.0 # Specific version
docker stop <container_id> && docker rm <container_id>
docker run --name n8n [options] -d docker.n8n.io/n8nio/n8n
Queue Mode Architecture
Queue mode separates n8n into distinct scaling components:
+------------------+
| Load Balancer |
+--------+---------+
|
+--------------+--------------+
| |
+--------v--------+ +--------v--------+
| Main Instance | | Webhook Processor|
| (triggers, | | (optional, for |
| scheduling) | | high traffic) |
+--------+--------+ +--------+---------+
| |
+-------------+---------------+
|
+-------v-------+
| Redis |
| (BullMQ) |
+-------+-------+
|
+-------------+-------------+
| | |
+--------v--+ +------v----+ +-----v-----+
| Worker 1 | | Worker 2 | | Worker N |
+--------+---+ +------+----+ +-----+-----+
| | |
+-------------+-------------+
|
+-------v-------+
| PostgreSQL |
+---------------+
Queue Mode Requirements
- PostgreSQL 13+ (NEVER SQLite)
- Redis for message queue
- S3-compatible storage for binary data
- Same n8n version on ALL instances
- Same
N8N_ENCRYPTION_KEYon ALL instances - Session-persistent load balancer for multi-main
Starting Workers
# Native
n8n worker
n8n worker --concurrency=5
# Docker
docker run --name n8n-worker \
-e EXECUTIONS_MODE=queue \
-e QUEUE_BULL_REDIS_HOST=redis-host \
-e N8N_ENCRYPTION_KEY=<shared-key> \
-e DB_TYPE=postgresdb \
-e DB_POSTGRESDB_HOST=postgres-host \
-e DB_POSTGRESDB_DATABASE=n8n \
-e DB_POSTGRESDB_PASSWORD=secret \
docker.n8n.io/n8nio/n8n worker
Webhook Processor (Optional)
# Separate webhook handler for high-traffic setups
docker run --name n8n-webhook -p 5679:5678 \
-e EXECUTIONS_MODE=queue \
-e QUEUE_BULL_REDIS_HOST=redis-host \
-e N8N_ENCRYPTION_KEY=<shared-key> \
docker.n8n.io/n8nio/n8n webhook
CLI Commands
Workflow Operations
n8n execute --id <ID> # Execute workflow
n8n update:workflow --id=<ID> --active=true # Activate
n8n update:workflow --id=<ID> --active=false # Deactivate
n8n update:workflow --all --active=false # Deactivate all
Export
n8n export:workflow --all --output=backups/ # All workflows
n8n export:workflow --id=<ID> --output=workflow.json # Single workflow
n8n export:workflow --backup --output=backups/latest/ # Backup format
n8n export:credentials --backup --output=backups/creds/ # All credentials
n8n export:credentials --all --decrypted --output=dec.json # DANGER: decrypted
Import
n8n import:workflow --input=file.json # From file
n8n import:workflow --separate --input=backups/latest/ # From directory
n8n import:credentials --input=file.json # Credentials
Other CLI
n8n audit # Security audit
n8n license:info # License details
n8n user-management:reset # Reset user mgmt
n8n mfa:disable --email=user@example.com # Disable MFA
Backup Strategies
Strategy 1: CLI Export (Small Instances)
n8n export:workflow --backup --output=/backups/workflows/
n8n export:credentials --backup --output=/backups/credentials/
Strategy 2: Database Dump (Production)
pg_dump -U postgres n8n > /backups/n8n-$(date +%Y%m%d).sql
# With Docker:
docker exec postgres pg_dump -U postgres n8n > /backups/n8n-$(date +%Y%m%d).sql
Strategy 3: Volume Backup (SQLite Only)
docker stop n8n
docker run --rm -v n8n_data:/data -v $(pwd)/backup:/backup \
alpine tar czf /backup/n8n-data.tar.gz /data
docker start n8n
Critical Backup Items
- Workflow definitions (JSON export)
- Credentials (encrypted export — ALWAYS needs same
N8N_ENCRYPTION_KEYto restore) N8N_ENCRYPTION_KEYitself (store securely, separate from backups)- Database (PostgreSQL dump or SQLite file copy)
- Binary data (filesystem path or S3 bucket)
Production Checklist
- PostgreSQL database (NOT SQLite)
N8N_ENCRYPTION_KEYexplicitly set and backed up securelyNODE_ENV=productionN8N_PROTOCOL=httpswith TLS termination (Traefik/nginx/Caddy)WEBHOOK_URLset to public-facing URLN8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=trueN8N_RUNNERS_ENABLED=true- Execution data pruning configured (
EXECUTIONS_DATA_PRUNE=true) - Regular automated backups (database + encryption key)
- Reverse proxy with HTTPS and rate limiting
Reference Files
- references/methods.md — Complete environment variable reference (100+ vars by category)
- references/examples.md — Docker Compose production configs, queue mode setup, CLI scripts, backup automation
- references/anti-patterns.md — Deployment mistakes, security misconfigurations, scaling pitfalls
Related skills