How do you self-host n8n on a VPS?

Quick Answer: Self-host n8n by provisioning a VPS (minimum 2 vCPU, 4 GB RAM — Hetzner CX22 at EUR 5.50/month is a strong option), installing Docker, creating a docker-compose.yml with PostgreSQL, setting up a reverse proxy with SSL (Caddy is simplest), and configuring automated backups. Production deployments should use PostgreSQL (not SQLite) and include daily pg_dump backups.

Why Self-Host n8n

Self-hosting n8n eliminates per-execution pricing, gives teams full control over data residency, and allows connecting to internal services behind your firewall. The community edition is free with unlimited workflows and executions. The trade-off is that you are responsible for infrastructure, updates, and backups.

Step 1: Choose a VPS Provider

n8n runs well on any Linux VPS. Common choices:

Provider Minimum Plan Monthly Cost Notes
Hetzner CX22 (2 vCPU, 4 GB) EUR 5.50 Best price/performance in EU
DigitalOcean Basic (2 vCPU, 4 GB) $24 Good documentation
AWS Lightsail Medium (2 vCPU, 4 GB) $20 AWS ecosystem integration
Contabo VPS S (4 vCPU, 8 GB) EUR 6.99 Budget option, larger specs

Step 2: Minimum Server Specifications

  • CPU: 2 vCPU (4 vCPU recommended for 20+ active workflows)
  • RAM: 4 GB (8 GB recommended for heavy workloads)
  • Storage: 20 GB SSD minimum
  • OS: Ubuntu 22.04 LTS or Debian 12

Step 3: Install Docker and Docker Compose

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

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

# Install Docker Compose plugin
sudo apt install docker-compose-plugin -y

# Verify installation
docker --version
docker compose version

Step 4: Create Docker Compose Configuration

Create a directory for n8n and the configuration file:

mkdir -p /opt/n8n && cd /opt/n8n

Create docker-compose.yml:

version: "3.8"
services:
  n8n-db:
    image: postgres:16-alpine
    restart: always
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db_data:/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:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=n8n-db
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${DB_PASSWORD}
      - N8N_HOST=${N8N_HOST}
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://${N8N_HOST}/
      - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=UTC
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      n8n-db:
        condition: service_healthy

volumes:
  db_data:
  n8n_data:

Step 5: Configure PostgreSQL

Create a .env file:

N8N_HOST=n8n.yourdomain.com
DB_PASSWORD=$(openssl rand -base64 24)
ENCRYPTION_KEY=$(openssl rand -hex 16)

PostgreSQL is required for production deployments. SQLite (the default) does not handle concurrent executions reliably and lacks proper backup tooling.

Step 6: Set Up a Reverse Proxy with SSL

Install Caddy for automatic HTTPS:

sudo apt install -y caddy

Add to /etc/caddy/Caddyfile:

n8n.yourdomain.com {
    reverse_proxy localhost:5678
}

Caddy automatically provisions and renews Let's Encrypt certificates.

Step 7: Start n8n

cd /opt/n8n
docker compose up -d

Verify n8n is running:

docker compose logs -f n8n

Navigate to https://n8n.yourdomain.com to complete the initial setup.

Step 8: Configure Automated Backups

Create a backup script at /opt/n8n/backup.sh:

#!/bin/bash
DATE=$(date +%Y-%m-%d)
BACKUP_DIR=/opt/n8n/backups
mkdir -p $BACKUP_DIR
docker exec n8n-db-1 pg_dump -U n8n n8n | gzip > $BACKUP_DIR/n8n_$DATE.sql.gz
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete

Add to crontab to run daily at 2am:

chmod +x /opt/n8n/backup.sh
echo "0 2 * * * /opt/n8n/backup.sh" | crontab -

Production Checklist

  • PostgreSQL with a strong, generated password
  • Encryption key generated and backed up securely
  • HTTPS via reverse proxy (Caddy or Nginx)
  • Firewall allows only ports 22, 80, 443
  • Automated daily database backups
  • Backup restoration tested at least once
  • Docker image pinned to a specific version for stability
  • Unattended security updates enabled

Editor's Note: We use Hetzner CX22 (EUR 5.50/month, 2 vCPU, 4 GB RAM) for most client n8n deployments. One client has been running on this configuration for 14 months, processing approximately 2,300 executions per day across 18 active workflows, with zero unplanned downtime. The critical lesson we learned early: automated PostgreSQL backups are non-negotiable. We lost a client's 3 months of execution history before standardizing the backup script above. The database was recoverable from Docker volumes, but the incident prompted us to implement daily pg_dump backups with 30-day retention and weekly off-site sync to a separate storage service. Total monthly infrastructure cost for a production n8n instance: EUR 5.50-11.00 depending on specs.

Related Questions

Written & reviewed by Rafal Fila · Last updated:

Related Tools

Related Rankings

Dive Deeper

comparison

Keystroke vs n8n in 2026: Agent-Built TypeScript vs the Visual Canvas

Keystroke, launched in July 2026 by Y Combinator W24 company Sprint Labs, is a code-first automation platform where AI coding agents write workflows as TypeScript in the user's repository. n8n, founded in 2019, is the most widely deployed source-available visual workflow platform, with 200,000+ users and a $2.5 billion valuation. This comparison covers the agent-authored versus canvas building models, durable execution, licensing (Elastic License 2.0 vs the Sustainable Use License), verified July 2026 pricing including Keystroke's usage metering, and the maturity gap between a days-old platform and an established ecosystem.

comparison

QuantumBPM vs Camunda 2026: Single-Binary Challenger vs the BPMN Incumbent

QuantumBPM (launched 2026, Coroid s.r.o., Slovakia) packages a BPMN 2.0 runtime and DMN 1.5 decision engine into one Go binary backed by Temporal and PostgreSQL. Camunda (Berlin, founded 2013) is the category incumbent: Camunda 7 (Apache 2.0, in maintenance) and the Zeebe-based Camunda 8 platform. This comparison covers product structure, architecture, DMN TCK conformance with recording dates, deployment, pricing, and vendor maturity, verified July 2026.

case-study

Migrating 23 Make Scenarios to Self-Hosted n8n: a 3-Week Breakdown

Anonymized retrospective of a DTC ecommerce brand migrating 23 Make scenarios to a self-hosted n8n instance over three weeks. Tooling cost dropped from $348/month on Make Teams to roughly $12/month on a Hetzner VPS, but credential and webhook recreation consumed about 40% of total project time.