Why Self-Host n8n?
n8n Cloud is convenient, but self-hosting gives you:
- No execution limits — run unlimited workflows on your own hardware
- Data privacy — credentials and workflow data never leave your server
- Cost control — a $6/month VPS handles most small-to-medium workloads
- Full customization — custom nodes, environment variables, filesystem access
This guide sets up a production-grade n8n instance with Docker Compose, PostgreSQL, and an Nginx reverse proxy.
Prerequisites
- A VPS or server running Ubuntu 22.04+ (4GB RAM minimum)
- Docker and Docker Compose installed
- A domain name pointing to your server’s IP
Step 1: Server Setup
# Update system
sudo apt update && sudo apt upgrade -y
# Install Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Install Docker Compose
sudo apt install docker-compose-plugin -y
# Verify
docker --version
docker compose version
Step 2: Directory Structure
mkdir -p ~/n8n/{data,postgres,files}
cd ~/n8n
Step 3: Docker Compose Configuration
Create ~/n8n/docker-compose.yml:
version: "3.8"
services:
postgres:
image: postgres:15
restart: always
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: n8nio/n8n:latest
restart: always
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}
# General
N8N_HOST: ${N8N_HOST}
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: https://${N8N_HOST}/
# Security
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
# Optional: basic auth
# N8N_BASIC_AUTH_ACTIVE: "true"
# N8N_BASIC_AUTH_USER: admin
# N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD}
# Timezone
GENERIC_TIMEZONE: America/New_York
# Execution settings
EXECUTIONS_DATA_PRUNE: "true"
EXECUTIONS_DATA_MAX_AGE: 336 # keep 14 days of execution history
volumes:
- ./data:/home/node/.n8n
- ./files:/files # for Read/Write File nodes
depends_on:
postgres:
condition: service_healthy
Step 4: Environment Variables
Create ~/n8n/.env:
# Generate a strong password
POSTGRES_PASSWORD=$(openssl rand -base64 32)
echo "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}"
# Generate encryption key (must be consistent — never change after first run)
N8N_ENCRYPTION_KEY=$(openssl rand -base64 32)
echo "N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}"
Edit ~/n8n/.env:
POSTGRES_PASSWORD=your-generated-password-here
N8N_ENCRYPTION_KEY=your-generated-key-here
N8N_HOST=n8n.yourdomain.com
Critical: Back up N8N_ENCRYPTION_KEY. If lost, all stored credentials are unrecoverable.
Step 5: Start n8n
cd ~/n8n
docker compose up -d
# Check logs
docker compose logs -f n8n
# Verify containers are running
docker compose ps
Step 6: Nginx Reverse Proxy with SSL
Install Nginx and Certbot:
sudo apt install nginx certbot python3-certbot-nginx -y
Create /etc/nginx/sites-available/n8n:
server {
listen 80;
server_name n8n.yourdomain.com;
location / {
proxy_pass http://localhost:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
}
}
Enable and get SSL certificate:
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Get free SSL certificate
sudo certbot --nginx -d n8n.yourdomain.com
Certbot auto-configures HTTPS and sets up automatic renewal.
Step 7: Enable User Authentication
For production, always enable authentication. Add to .env:
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your-secure-password
Or use n8n’s built-in User Management (recommended for teams):
- After first login, go to Settings → Users
- Create accounts with role-based access (owner / admin / member)
Updates and Maintenance
Update n8n to latest version:
cd ~/n8n
docker compose pull n8n
docker compose up -d n8n
Backup the database:
# Dump PostgreSQL database
docker compose exec postgres pg_dump -U n8n n8n > backup-$(date +%Y%m%d).sql
# Restore from backup
docker compose exec -T postgres psql -U n8n n8n < backup-20260408.sql
Monitor disk usage (execution history grows fast):
docker system df
du -sh ~/n8n/postgres/
The EXECUTIONS_DATA_MAX_AGE: 336 setting (14 days) in your compose file automatically prunes old execution history.
Performance Tuning
For high-throughput installations:
Increase workers:
# docker-compose.yml
n8n:
environment:
EXECUTIONS_MODE: queue
QUEUE_BULL_REDIS_HOST: redis
N8N_CONCURRENCY_PRODUCTION_LIMIT: 20
redis:
image: redis:7
restart: always
Queue mode with Redis enables horizontal scaling — run multiple n8n worker containers processing jobs from a shared queue.
PostgreSQL connection pool:
DB_POSTGRESDB_CONNECTION_LIMIT: 10
Monitoring
Check n8n health endpoint:
curl https://n8n.yourdomain.com/healthz
# → {"status":"ok"}
Set up uptime monitoring with UptimeRobot (free) or your preferred tool — monitor /healthz every 5 minutes.
View execution stats:
- n8n UI → Settings → Execution History — see all past runs
- Filter by failed executions to catch silent errors
Frequently Asked Questions
Can I migrate from n8n Cloud to self-hosted?
Yes. Export all workflows from n8n Cloud (Settings → Export Workflows), download credentials, then import to your self-hosted instance. Re-enter credentials (they are encrypted and can’t be exported directly).
How much server resources do I need?
- Light use (< 100 executions/day): 1 vCPU, 1GB RAM
- Medium use (100–1,000/day): 2 vCPU, 2GB RAM
- Heavy use (1,000+/day): 4+ vCPU, 4GB RAM, Redis queue mode
A $6–12/month VPS (Hetzner, DigitalOcean, Hostinger) handles most use cases.
What happens if n8n crashes?
restart: always in Docker Compose ensures n8n restarts automatically. Combine with a process monitor like systemd:
sudo systemctl enable docker
Docker containers restart on system reboot too.
How do I run n8n workflows from the command line?
# Trigger a workflow via n8n CLI
docker compose exec n8n n8n execute --id WORKFLOW_ID
Or via webhook using curl — every active webhook workflow has a URL you can call programmatically.
Is self-hosted n8n free?
Yes — n8n is source-available under the Sustainable Use License. Self-hosting is free for personal and business use (commercial restrictions apply for building n8n-based products for resale).
Next Steps
- n8n Webhook and API Automation — Build integrations on your self-hosted instance
- n8n RAG Pipeline with Vector Database — Add AI-powered document retrieval
- Building AI Workflows with n8n — Core n8n concepts