Why self-host n8n?
n8n is one of the most popular automation tools for technical teams. You get control, lower costs at scale, and full access to your workflow data. The downside: most install guides stop at a demo setup. This guide gives you a production-ready baseline.
Recommended VPS Specifications
- CPU: 2 vCPU minimum (4 vCPU recommended)
- RAM: 4GB minimum (8GB recommended)
- Storage: 60GB+ SSD
- OS: Ubuntu 22.04/24.04 LTS
- Stack: Docker Compose + PostgreSQL + Redis
For this setup, a Cloud VPS with predictable resources is ideal.
Step 1: Create project directory
>mkdir -p ~/n8n && cd ~/n8n
mkdir -p n8n_data postgres_data redis_data
Step 2: Create Docker Compose file
>cat > docker-compose.yml <<'YAML'
services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: change-this-password
POSTGRES_DB: n8n
volumes:
- ./postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- ./redis_data:/data
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- NODE_ENV=production
- WEBHOOK_URL=https://n8n.example.com/
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=change-this-password
- QUEUE_BULL_REDIS_HOST=redis
- QUEUE_BULL_REDIS_PORT=6379
- EXECUTIONS_MODE=queue
- N8N_ENCRYPTION_KEY=replace-with-long-random-key
depends_on:
- postgres
- redis
volumes:
- ./n8n_data:/home/node/.n8n
YAML
Step 3: Start the stack
>docker compose pull
docker compose up -d
docker compose ps
Step 4: Reverse proxy + SSL (Nginx)
>sudo apt update && sudo apt install -y nginx certbot python3-certbot-nginx
>sudo nano /etc/nginx/sites-available/n8n
>server {
listen 80;
server_name n8n.example.com;
location / {
proxy_pass http://127.0.0.1:5678;
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;
}
}
>sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d n8n.example.com
Common problems and fixes
1) Webhooks fail behind proxy
Set >WEBHOOK_URL to your public HTTPS URL and restart the n8n service.
>docker compose restart n8n
2) Memory spikes during execution
Use queue mode (already configured), increase RAM, and split workers on larger deployments.
3) DB connection errors after reboot
Verify service order and health, then check logs:
>docker compose logs --tail=200 postgres
docker compose logs --tail=200 n8n
Backup strategy (minimum viable)
># backup postgres + n8n data
cd ~/n8n
tar czf n8n-backup-$(date +%F).tar.gz n8n_data postgres_data redis_data
Final checklist
- HTTPS enabled
- Strong
>N8N_ENCRYPTION_KEYset - Regular backups scheduled
- Firewall open only for 22/80/443
If you need stable performance for many workflows, move to a higher-memory Cloud VPS plan before you hit limits.
Security lockdown (important)
Do not expose OpenClaw wide open on the public internet. Use a reverse proxy, TLS, and firewall restrictions. Follow our hardening guide: OpenClaw Security Lockdown: Safe Internet Exposure Guide.


Be First to Comment