Self-Hosting n8n: A Complete 2026 Setup Guide
Step-by-step guide to deploying n8n on your own infrastructure in 2026 — Docker, environment configuration, SSL, backups, and what to watch for in production.
Self-hosting n8n gets you full control over your data, predictable costs, and unlimited workflow executions — all for the price of a $15/month VPS. The tradeoff: you're responsible for setup, updates, and keeping the lights on.
This guide walks through a production-ready n8n deployment in about 90 minutes. We use this exact stack for the n8n instances we host on behalf of clients.
Prerequisites
- A domain name (or subdomain) you control. We'll use
n8n.yourcompany.comfor examples. - A VPS with at least 2 GB RAM and 1 vCPU. DigitalOcean's $12/month Basic droplet is the sweet spot for most teams. AWS Lightsail and Hetzner CX22 work equally well.
- SSH access to that VPS, with a non-root sudo user configured.
- About 90 minutes.
Step 1: Server setup (10 min)
SSH into your VPS and install Docker. On Ubuntu 24.04:
sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
exit # log out and back in for the group change to apply
Confirm Docker works:
docker run --rm hello-world
Step 2: DNS pointing (5 min)
In your DNS provider, add an A record pointing n8n.yourcompany.com to your VPS's public IP address. Let it propagate (usually 1–5 minutes).
Step 3: Docker Compose configuration (15 min)
Create a working directory and a docker-compose.yml file:
mkdir -p ~/n8n && cd ~/n8n
Paste this into ~/n8n/docker-compose.yml:
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes:
- postgres_data:/var/lib/postgresql/data
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_HOST: ${N8N_HOST}
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: https://${N8N_HOST}/
GENERIC_TIMEZONE: America/New_York
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
depends_on:
- postgres
volumes:
- n8n_data:/home/node/.n8n
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
volumes:
postgres_data:
n8n_data:
caddy_data:
caddy_config:
Create a .env file in the same directory:
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 24)
N8N_HOST=n8n.yourcompany.com
N8N_ENCRYPTION_KEY=$(openssl rand -hex 24)
EOF
chmod 600 .env
The encryption key is critical — it encrypts your credentials inside n8n. Back this up somewhere secure. If you lose it, every saved credential becomes unreadable.
Step 4: Caddy reverse proxy + auto-SSL (5 min)
Create ~/n8n/Caddyfile:
n8n.yourcompany.com {
reverse_proxy n8n:5678
}
Caddy will automatically obtain a Let's Encrypt SSL certificate when it starts.
Step 5: Start everything (5 min)
cd ~/n8n
docker compose up -d
docker compose logs -f n8n
You should see n8n start. Once you see Editor is now accessible via: https://n8n.yourcompany.com/, hit Ctrl+C to exit the logs (the container keeps running).
Visit https://n8n.yourcompany.com in your browser. You'll be prompted to create the owner account. Use a real email — n8n uses it for password recovery, and there's no built-in "I forgot my admin password" flow for self-hosted instances.
Step 6: Production hardening
A working n8n instance isn't a production-ready n8n instance. Don't skip these.
Backup the database nightly. Add this to root's crontab:
0 2 * * * cd /home/youruser/n8n && docker compose exec -T postgres pg_dump -U n8n n8n | gzip > /home/youruser/backups/n8n-$(date +\%Y\%m\%d).sql.gz
Rotate to keep the last 30 days. Push to S3 / Backblaze B2 weekly for off-site copies.
Enable basic auth on the editor (separate from the n8n user account):
# Add to the n8n service environment block:
N8N_BASIC_AUTH_ACTIVE: "true"
N8N_BASIC_AUTH_USER: ${BASIC_AUTH_USER}
N8N_BASIC_AUTH_PASSWORD: ${BASIC_AUTH_PASSWORD}
Monitor uptime. Free options: UptimeRobot, BetterStack, or self-hosted Uptime Kuma. Check https://n8n.yourcompany.com/healthz every 60 seconds.
Subscribe to n8n's security advisories at https://github.com/n8n-io/n8n/security/advisories. Critical patches roll out monthly.
Updates
cd ~/n8n
docker compose pull
docker compose up -d
Major-version upgrades occasionally have breaking changes. Always read the release notes first, and test in staging before pulling into production.
When self-hosting isn't worth it
A few cases where n8n Cloud is the better call:
- You don't have anyone comfortable with Docker or Linux.
- Your workflow volume is genuinely low (< 1,000 executions/month).
- Compliance requirements specifically want a managed/SOC2 environment.
For everyone else: self-hosting routinely saves $200–$500/month versus n8n Cloud or Zapier equivalents.
What we do for clients
We host and manage production n8n instances for B2B operations teams who want self-hosted control but don't want to babysit the infrastructure. Everything in this guide, plus monitoring, backup verification, monthly patching, and 24-hour incident response.
If that's interesting, book a 30-minute discovery call and we'll talk through your stack. Or browse the automation catalogue for the workflows we ship most often.
Want us to automate this for you?
Book a 30-minute discovery call — no pressure, no commitment.