← all posts
n8n · self-hosting
2026-04-20 9 min read

Self-Hosting n8n: Complete Setup Guide (2026)

Skip the cloud subscription. Run n8n on your own VPS for under $10/month — Docker, Caddy for HTTPS, PostgreSQL for scale. This is exactly how we do it in production.

We've deployed n8n on VPS infrastructure for dozens of clients. The cloud version is convenient, but the pricing model doesn't scale. Self-hosting is cheaper, faster, and you own your data. This guide covers production-grade setup, not a demo.

What You Need

Step 1: Install Docker

# Update system
sudo apt update && sudo apt upgrade -y

# Install Docker
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER && newgrp docker

# Verify
docker --version && docker compose version

Step 2: Point DNS to Your Server

Add an A record in your DNS panel:

Type: A
Name: n8n
Value: YOUR.SERVER.IP
TTL: 300

Confirm propagation: dig n8n.yourdomain.com +short

Step 3: Docker Compose Config

mkdir ~/n8n-stack && cd ~/n8n-stack && nano docker-compose.yml
version: '3.8'

services:
  n8n:
    image: n8nio/n8n:latest
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=n8n.yourdomain.com
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.yourdomain.com/
      - NODE_ENV=production
      - GENERIC_TIMEZONE=Europe/London
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=changeme123
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

Change N8N_BASIC_AUTH_PASSWORD to something strong before proceeding.

Step 4: HTTPS with Caddy

# Install Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
# /etc/caddy/Caddyfile
n8n.yourdomain.com {
  reverse_proxy localhost:5678
}
sudo systemctl reload caddy

Caddy auto-provisions Let's Encrypt certs. No certbot. No manual renewal.

Step 5: Launch

cd ~/n8n-stack && docker compose up -d

Visit https://n8n.yourdomain.com — you should see the login screen within 30 seconds.

what you have now
n8n running on your VPS, fully under your control
HTTPS with auto-renewing Let's Encrypt certificate
Basic auth on the UI
Auto-restart on reboot (restart: always)
Persistent data in Docker volume

Production Hardening

Add PostgreSQL for Scale

Default SQLite works under low load. Above ~1000 executions/day, switch to Postgres:

services:
  postgres:
    image: postgres:15
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=strongpassword
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data

  n8n:
    # add to environment:
    - DB_TYPE=postgresdb
    - DB_POSTGRESDB_HOST=postgres
    - DB_POSTGRESDB_USER=n8n
    - DB_POSTGRESDB_PASSWORD=strongpassword
    - DB_POSTGRESDB_DATABASE=n8n
    depends_on: [postgres]

Cost: Self-Host vs Cloud

optionmonthlyexecutionsworkflows
n8n Cloud Starter$242,500/mo5 active
n8n Cloud Pro$6010,000/mo15 active
Self-hosted (Hetzner CX21)~$5unlimitedunlimited

When Cloud Makes Sense

quick checklist
VPS with 2GB+ RAM, Ubuntu 22.04
Docker + Docker Compose installed
DNS A record pointing at server IP
docker-compose.yml with n8n config
Caddy configured as reverse proxy
UFW firewall + Fail2ban enabled
PostgreSQL added for production load
Uptime monitoring via Uptime Kuma

Need this done for you? We set up and maintain n8n infrastructure as part of our automation builds. Get in touch →