🐳 Docker Power! Met Docker kun je N8N in enkele minuten deployen, schalen en beheren. Deze gids behandelt alles van basis installatie tot enterprise-ready setups met automatische backups, SSL en monitoring.
1. Waarom N8N met Docker? 🚀
Docker is de meest populaire deployment methode voor N8N, en daar zijn goede redenen voor:
✅ Voordelen van Docker
- Snelle deployment: N8N draait binnen minuten
- Isolatie: Geen conflicten met system packages
- Portabiliteit: Draait overal waar Docker draait
- Versie management: Makkelijk upgraden/downgraden
- Schaalbaarheid: Multi-container setups mogelijk
- Reproduceerbaar: Identieke environments
🎯 Perfect voor
- Development: Lokale test omgevingen
- Staging: Pre-productie testing
- Productie: Enterprise deployments
- CI/CD: Automated deployments
- Cloud: AWS, Azure, GCP, DigitalOcean
- On-premise: Eigen servers
2. Systeemvereisten & Voorbereiding 📋
Minimale Hardware Vereisten
| Component | Development | Productie | Enterprise |
|---|---|---|---|
| CPU | 2 vCPU | 4 vCPU | 8+ vCPU |
| RAM | 2 GB | 4-8 GB | 16+ GB |
| Storage | 10 GB SSD | 40 GB SSD | 100+ GB SSD |
| OS | Ubuntu 22.04+, Debian 11+, CentOS 8+, of Windows met WSL2 | ||
Docker Installatie
# Ubuntu/Debian - Officiële Docker installatie script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Voeg gebruiker toe aan docker groep (geen sudo nodig)
sudo usermod -aG docker $USER
newgrp docker
# Installeer Docker Compose v2
sudo apt-get update
sudo apt-get install docker-compose-plugin
# Verifieer installatie
docker --version
docker compose version
⚠️ Belangrijk voor Windows gebruikers
Gebruik WSL2 met Docker Desktop voor de beste ervaring. Native Windows containers worden niet ondersteund.
3. Quick Start: N8N in 5 Minuten ⚡
De snelste manier om N8N te starten met Docker:
Optie 1: Docker Run (Simpel)
# Basis N8N container starten
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
# Met basic authentication
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e N8N_BASIC_AUTH_ACTIVE=true \
-e N8N_BASIC_AUTH_USER=admin \
-e N8N_BASIC_AUTH_PASSWORD=password \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n
Open nu je browser en ga naar: http://localhost:5678
Optie 2: Docker Compose (Aanbevolen)
Maak een docker-compose.yml bestand:
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=changeme
- N8N_ENCRYPTION_KEY=your-encryption-key-min-32-chars-long
- TZ=Europe/Amsterdam
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
volumes:
n8n_data:
Start N8N met:
# Start in detached mode
docker compose up -d
# Bekijk logs
docker compose logs -f n8n
# Stop N8N
docker compose down
4. Docker Compose Configuratie 🔧
Voor productie gebruik je een uitgebreidere Docker Compose configuratie:
Complete docker-compose.yml
version: '3.8'
services:
n8n:
image: n8nio/n8n:1.64.0 # Gebruik altijd specifieke versies in productie!
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
# Database configuratie
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# Security
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
# Network configuratie
- N8N_HOST=0.0.0.0
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.jouwdomein.nl
- N8N_EDITOR_BASE_URL=https://n8n.jouwdomein.nl
# Performance
- NODE_OPTIONS=--max-old-space-size=4096
- N8N_DEFAULT_BINARY_DATA_MODE=filesystem
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=336
# Timezone
- TZ=Europe/Amsterdam
- GENERIC_TIMEZONE=Europe/Amsterdam
# Logging
- N8N_LOG_LEVEL=info
- N8N_LOG_OUTPUT=console
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
- ./backups:/backups
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:5678/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
deploy:
resources:
limits:
memory: 4G
cpus: '2'
reservations:
memory: 2G
cpus: '1'
postgres:
image: postgres:15-alpine
container_name: n8n-postgres
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_NON_ROOT_USER=n8n
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db.sql:/docker-entrypoint-initdb.d/init.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
interval: 10s
timeout: 5s
retries: 5
volumes:
n8n_data:
driver: local
postgres_data:
driver: local
networks:
default:
name: n8n_network
driver: bridge
.env File (Environment Variables)
Maak een .env bestand voor gevoelige informatie:
# Database
POSTGRES_PASSWORD=super_secure_database_password_here
# N8N Security
N8N_ENCRYPTION_KEY=your-32-character-encryption-key-minimum
N8N_USER=admin
N8N_PASSWORD=your_secure_admin_password
# External services (optional)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
🔐 Security Waarschuwing!
Voeg nooit je .env bestand toe aan Git! Voeg het toe aan .gitignore:
echo ".env" >> .gitignore
5. Database Setup (PostgreSQL/MySQL) 🗄️
Voor productie gebruik je altijd een externe database in plaats van SQLite:
PostgreSQL Setup (Aanbevolen)
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: n8n-postgres
restart: unless-stopped
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
# Automatische backup elke nacht om 2:00
- ./backup-script.sh:/etc/periodic/daily/backup:ro
ports:
- "5432:5432" # Alleen voor debugging, verwijder in productie
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- DB_POSTGRESDB_SCHEMA=public
depends_on:
postgres:
condition: service_healthy
MySQL Setup (Alternatief)
services:
mysql:
image: mysql:8
container_name: n8n-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: n8n
MYSQL_USER: n8n
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
n8n:
environment:
- DB_TYPE=mysqldb
- DB_MYSQLDB_HOST=mysql
- DB_MYSQLDB_PORT=3306
- DB_MYSQLDB_DATABASE=n8n
- DB_MYSQLDB_USER=n8n
- DB_MYSQLDB_PASSWORD=${MYSQL_PASSWORD}
Database Performance Tips
- ✅ Gebruik PostgreSQL voor beste performance
- ✅ Configureer connection pooling voor high-traffic
- ✅ Stel memory limits in voor database container
- ✅ Enable query logging voor debugging
- ✅ Implementeer automatische backups
6. Environment Variables Uitgelegd 📝
N8N heeft vele environment variables voor configuratie. Hier zijn de belangrijkste:
🔐 Security Variables
| Variable | Beschrijving | Voorbeeld |
|---|---|---|
N8N_ENCRYPTION_KEY |
Encryptie voor credentials (min 32 chars) | 32-char-long-encryption-key-here |
N8N_BASIC_AUTH_ACTIVE |
Activeer basic authentication | true |
N8N_BASIC_AUTH_USER |
Username voor login | admin |
N8N_BASIC_AUTH_PASSWORD |
Password voor login | SecurePassword123! |
🌐 Network Variables
| Variable | Beschrijving | Voorbeeld |
|---|---|---|
N8N_HOST |
Bind address | 0.0.0.0 |
N8N_PORT |
Port nummer | 5678 |
N8N_PROTOCOL |
Protocol (http/https) | https |
WEBHOOK_URL |
Publieke webhook URL | https://n8n.domain.nl |
N8N_EDITOR_BASE_URL |
Editor URL | https://n8n.domain.nl |
⚡ Performance Variables
# Memory management
NODE_OPTIONS=--max-old-space-size=4096
# Binary data mode (filesystem is sneller dan database)
N8N_DEFAULT_BINARY_DATA_MODE=filesystem
# Execution pruning (verwijder oude executions)
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=336 # 14 dagen
# Queue mode voor scaling
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=redis
QUEUE_BULL_REDIS_PORT=6379
7. SSL & Reverse Proxy (Traefik/Nginx) 🔒
Voor productie heb je altijd SSL/HTTPS nodig. Hier zijn twee populaire opties:
Optie 1: Traefik (Automatische SSL)
version: '3.8'
services:
traefik:
image: traefik:v3.0
container_name: traefik
restart: unless-stopped
ports:
- "80:80"
- "443:443"
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=jouw@email.nl
- --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
# Redirect HTTP naar HTTPS
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- traefik_data:/letsencrypt
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
environment:
- N8N_PROTOCOL=https
- N8N_HOST=n8n.jouwdomein.nl
- WEBHOOK_URL=https://n8n.jouwdomein.nl
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`n8n.jouwdomein.nl`)"
- "traefik.http.routers.n8n.entrypoints=websecure"
- "traefik.http.routers.n8n.tls.certresolver=letsencrypt"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
traefik_data:
Optie 2: Nginx Reverse Proxy
Maak een nginx.conf bestand:
server {
listen 80;
server_name n8n.jouwdomein.nl;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.jouwdomein.nl;
# SSL Certificaten (gebruik Certbot voor Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/n8n.jouwdomein.nl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.jouwdomein.nl/privkey.pem;
# SSL Security Headers
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Proxy Headers
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;
# WebSocket Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Proxy naar N8N
location / {
proxy_pass http://n8n:5678;
proxy_buffer_size 16k;
proxy_buffers 8 16k;
proxy_read_timeout 600s;
}
}
8. Volumes & Data Persistentie 💾
Correct volume management is cruciaal voor data persistentie:
Volume Configuratie
services:
n8n:
volumes:
# ESSENTIEEL: N8N data directory
- n8n_data:/home/node/.n8n
# Lokale bestanden voor workflows
- ./local-files:/files
# Custom nodes (optioneel)
- ./custom-nodes:/home/node/.n8n/nodes
# Backup directory
- ./backups:/backups
# SSL certificaten (read-only)
- ./certs:/etc/ssl/certs:ro
volumes:
n8n_data:
driver: local
driver_opts:
type: none
o: bind
device: /opt/n8n/data # Absolute pad op host
Belangrijke Directories
| Directory | Inhoud | Backup Nodig? |
|---|---|---|
/home/node/.n8n |
Workflows, credentials, settings | ✅ Ja, kritiek! |
/home/node/.n8n/nodes |
Custom/community nodes | ✅ Ja |
/files |
Lokale bestanden voor workflows | ⚠️ Afhankelijk van gebruik |
/home/node/.n8n/binaryData |
Binary data storage | ❌ Nee, kan groot worden |
9. Productie-Ready Setup 🏭
Een complete productie setup met alle bells and whistles:
version: '3.8'
services:
# Redis voor queue mode
redis:
image: redis:7-alpine
container_name: n8n-redis
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# PostgreSQL database
postgres:
image: postgres:15-alpine
container_name: n8n-postgres
restart: unless-stopped
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
interval: 10s
timeout: 5s
retries: 5
# N8N main instance
n8n:
image: n8nio/n8n:1.64.0
container_name: n8n-main
restart: unless-stopped
ports:
- "5678:5678"
environment:
# Database
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# Queue mode
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}
# Security
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
# Performance
- NODE_OPTIONS=--max-old-space-size=4096
- N8N_DEFAULT_BINARY_DATA_MODE=filesystem
- EXECUTIONS_DATA_PRUNE=true
- EXECUTIONS_DATA_MAX_AGE=168
# Network
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.jouwdomein.nl
- N8N_EDITOR_BASE_URL=https://n8n.jouwdomein.nl
# Timezone
- TZ=Europe/Amsterdam
- GENERIC_TIMEZONE=Europe/Amsterdam
# Logging
- N8N_LOG_LEVEL=info
volumes:
- n8n_data:/home/node/.n8n
- ./local-files:/files
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
deploy:
resources:
limits:
memory: 4G
cpus: '2'
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:5678/healthz"]
interval: 30s
timeout: 10s
retries: 3
# N8N worker voor heavy lifting
n8n-worker:
image: n8nio/n8n:1.64.0
container_name: n8n-worker
restart: unless-stopped
command: worker
environment:
# Zelfde database config
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
# Zelfde queue config
- EXECUTIONS_MODE=queue
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}
# Security
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
# Performance
- NODE_OPTIONS=--max-old-space-size=2048
volumes:
- n8n_data:/home/node/.n8n
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
deploy:
resources:
limits:
memory: 2G
cpus: '1'
replicas: 2 # Meerdere workers voor load balancing
volumes:
n8n_data:
postgres_data:
redis_data:
networks:
default:
name: n8n_production
driver: bridge
10. Backup & Restore Strategieën 💾
Regelmatige backups zijn essentieel voor disaster recovery:
Automatische Backup Script
Maak een backup.sh script:
#!/bin/bash
# N8N Backup Script
# Configuratie
BACKUP_DIR="/opt/backups/n8n"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
# Maak backup directory
mkdir -p $BACKUP_DIR
echo "🔵 Starting N8N backup: $DATE"
# 1. Database backup
echo "📦 Backing up PostgreSQL database..."
docker exec n8n-postgres pg_dump -U n8n -d n8n | gzip > $BACKUP_DIR/database_$DATE.sql.gz
# 2. N8N data volume backup
echo "📂 Backing up N8N data volume..."
docker run --rm \
-v n8n_data:/data \
-v $BACKUP_DIR:/backup \
alpine tar czf /backup/n8n_volume_$DATE.tar.gz -C /data .
# 3. Environment backup
echo "🔐 Backing up environment files..."
cp .env $BACKUP_DIR/env_$DATE.backup
cp docker-compose.yml $BACKUP_DIR/compose_$DATE.backup
# 4. Cleanup oude backups
echo "🧹 Cleaning old backups (older than $RETENTION_DAYS days)..."
find $BACKUP_DIR -name "*.gz" -mtime +$RETENTION_DAYS -delete
find $BACKUP_DIR -name "*.backup" -mtime +$RETENTION_DAYS -delete
echo "✅ Backup completed successfully!"
echo "📍 Location: $BACKUP_DIR"
ls -lh $BACKUP_DIR/*$DATE*
Maak het script executable en voeg toe aan crontab:
# Maak executable
chmod +x backup.sh
# Voeg toe aan crontab (dagelijks om 2:00 AM)
crontab -e
0 2 * * * /opt/scripts/backup.sh >> /var/log/n8n-backup.log 2>&1
Restore Procedure
Restore script (restore.sh):
#!/bin/bash
# N8N Restore Script
if [ $# -eq 0 ]; then
echo "Usage: ./restore.sh YYYYMMDD_HHMMSS"
echo "Example: ./restore.sh 20250825_020000"
exit 1
fi
BACKUP_DATE=$1
BACKUP_DIR="/opt/backups/n8n"
echo "⚠️ WARNING: This will restore N8N to backup from $BACKUP_DATE"
read -p "Are you sure? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
echo "Restore cancelled."
exit 1
fi
# Stop N8N
echo "🛑 Stopping N8N containers..."
docker-compose down
# Restore database
echo "📦 Restoring database..."
docker-compose up -d postgres
sleep 10
gunzip -c $BACKUP_DIR/database_$BACKUP_DATE.sql.gz | \
docker exec -i n8n-postgres psql -U n8n -d n8n
# Restore volume
echo "📂 Restoring N8N data..."
docker run --rm \
-v n8n_data:/data \
-v $BACKUP_DIR:/backup \
alpine sh -c "cd /data && tar xzf /backup/n8n_volume_$BACKUP_DATE.tar.gz"
# Restore environment
echo "🔐 Restoring environment files..."
cp $BACKUP_DIR/env_$BACKUP_DATE.backup .env
cp $BACKUP_DIR/compose_$BACKUP_DATE.backup docker-compose.yml
# Start N8N
echo "🚀 Starting N8N..."
docker-compose up -d
echo "✅ Restore completed!"
docker-compose ps
11. Updates & Rollback Procedures 🔄
Veilig updaten van N8N zonder downtime:
Update Strategie
#!/bin/bash
# N8N Update Script
NEW_VERSION="1.65.0"
OLD_VERSION=$(docker inspect n8n --format='{{.Config.Image}}' | cut -d: -f2)
echo "📊 Current version: $OLD_VERSION"
echo "🆕 New version: $NEW_VERSION"
# 1. Backup maken
echo "💾 Creating backup before update..."
./backup.sh
# 2. Pull nieuwe image
echo "📥 Pulling new N8N image..."
docker pull n8nio/n8n:$NEW_VERSION
# 3. Update docker-compose.yml
echo "📝 Updating docker-compose.yml..."
sed -i.bak "s/n8nio\/n8n:$OLD_VERSION/n8nio\/n8n:$NEW_VERSION/g" docker-compose.yml
# 4. Recreate containers (met minimal downtime)
echo "🔄 Recreating containers..."
docker-compose up -d --no-deps --build n8n
# 5. Health check
echo "🏥 Checking health..."
sleep 30
curl -f http://localhost:5678/healthz || {
echo "❌ Health check failed! Rolling back..."
./rollback.sh $OLD_VERSION
exit 1
}
echo "✅ Update completed successfully!"
docker-compose ps
Rollback Script
#!/bin/bash
# N8N Rollback Script
ROLLBACK_VERSION=$1
echo "⏪ Rolling back to version: $ROLLBACK_VERSION"
# Restore docker-compose.yml
cp docker-compose.yml.bak docker-compose.yml
# Recreate containers met oude versie
docker-compose up -d --force-recreate
echo "✅ Rollback completed!"
docker-compose ps
12. Monitoring & Health Checks 📊
Monitor je N8N installatie voor optimale performance:
Docker Health Checks
services:
n8n:
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:5678/healthz"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Monitoring met Prometheus & Grafana
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_INSTALL_PLUGINS=redis-datasource
volumes:
- grafana_data:/var/lib/grafana
- ./grafana-dashboards:/etc/grafana/provisioning/dashboards
Health Check Script
#!/bin/bash
# N8N Health Monitor
# Check N8N status
N8N_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5678/healthz)
if [ $N8N_STATUS -eq 200 ]; then
echo "✅ N8N is healthy"
else
echo "❌ N8N is unhealthy (HTTP $N8N_STATUS)"
# Send alert (email/Slack/Discord)
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"⚠️ N8N is down!"}' \
$SLACK_WEBHOOK_URL
fi
# Check database
docker exec n8n-postgres pg_isready -U n8n || {
echo "❌ Database is down!"
exit 1
}
# Check disk space
DISK_USAGE=$(df -h /opt/n8n | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 80 ]; then
echo "⚠️ Disk usage critical: $DISK_USAGE%"
fi
# Check memory
docker stats --no-stream --format "table {{.Container}}\t{{.MemUsage}}" | grep n8n
13. Troubleshooting & FAQ 🔧
Veelvoorkomende Problemen
❌ Problem: Container start niet
Symptoom: docker-compose up faalt
Oplossing:
# Check logs
docker-compose logs n8n
# Check permissions
sudo chown -R 1000:1000 ./n8n_data
# Clean restart
docker-compose down -v
docker-compose up -d
❌ Problem: Database connection failed
Symptoom: Error: "ECONNREFUSED"
Oplossing:
# Test database connectivity
docker exec n8n ping postgres
docker exec n8n nc -zv postgres 5432
# Check database logs
docker-compose logs postgres
# Verify credentials
docker exec postgres psql -U n8n -d n8n -c "SELECT 1;"
❌ Problem: Out of memory
Symptoom: Container crashes met "OOMKilled"
Oplossing:
# Increase memory limit
environment:
- NODE_OPTIONS=--max-old-space-size=8192
deploy:
resources:
limits:
memory: 8G
FAQ
Hoe upgrade ik van SQLite naar PostgreSQL?
Export je workflows via de UI, stop N8N, configureer PostgreSQL in docker-compose.yml, start N8N, importeer workflows.
Kan ik meerdere N8N instances draaien?
Ja! Gebruik queue mode met Redis en meerdere worker containers. Zie de productie setup sectie.
Hoe migreer ik naar een andere server?
Maak een backup, kopieer alle bestanden naar nieuwe server, restore backup, update DNS.
14. Best Practices & Security 🛡️
Security Checklist
- ✅ Gebruik specifieke versie tags, niet
:latest - ✅ Enable authentication (basic auth of SSO)
- ✅ Gebruik HTTPS met valid SSL certificaten
- ✅ Isoleer containers in eigen network
- ✅ Limit resources met deploy constraints
- ✅ Regelmatige updates voor security patches
- ✅ Gebruik secrets voor gevoelige data
- ✅ Monitor logs voor verdachte activiteit
- ✅ Backup encryption key veilig opslaan
- ✅ Firewall rules alleen noodzakelijke ports
Performance Tips
🚀 Database
- Gebruik PostgreSQL ipv SQLite
- Enable connection pooling
- Regelmatige VACUUM runs
- Index optimization
💾 Storage
- Gebruik SSD storage
- Binary data op filesystem
- Prune oude executions
- External object storage (S3)
🎯 Klaar om N8N met Docker te deployen?
Met deze complete gids heb je alle kennis om N8N professioneel te deployen. Van development tot enterprise-ready productie setups!
Wij installeren N8N voor je - €100 all-in! →📚 Aanvullende Resources
- Officiële N8N Docker Documentatie
- N8N op Docker Hub
- N8N Docker Examples op GitHub
- N8N Community Forum - Docker
"Docker maakt N8N deployment een fluitje van een cent. Van lokale development tot enterprise productie - alles draait smooth in containers!" - DevOps Engineer, 2025