TutorialNov 7, 20263 min read

Self-Host n8n on a VPS with Docker and HTTPS

Run your own n8n automation server on a Linux VPS: which size, Docker Compose with a persistent volume, automatic HTTPS with Caddy, the settings for webhooks and time zones, and how to update and back it up.

Short answer: self-hosting n8n takes a Linux VPS with 2 GB RAM ($6.50 a month), a domain pointing at it, and a short Docker Compose file with n8n and Caddy. Caddy gets the HTTPS certificate on its own. You end up with your own n8n at https://n8n.yourdomain.com, no execution limits, and your credentials on a server only you control.

n8n's cloud plans charge by executions. The self-hosted Community Edition is free to run on your own server for your own workflows; check n8n's Sustainable Use License if you plan to offer n8n to others as a service.

01Which Server

UsePlanPrice
A few workflows, light data1–2 vCPU, 2 GB RAM, 20 GB NVMe$6.50/month
Many workflows, AI nodes, larger files2 vCPU, 6 GB RAM, 40 GB NVMe$13/month
Busy instance with Postgres and queue mode6 vCPU, 10 GB RAM$26/month

The 1 GB plan is too tight once Docker, n8n and a few workflows with data are running.

Nano1 vCPU · 1 GB · 10 GB NVMe$3.90/mobilled monthlyBuy
Most popularSpark1 vCPU · 2 GB · 20 GB NVMe$6.50/mobilled monthlyBuy
Pulse2 vCPU · 2 GB · 20 GB NVMe$6.50/mobilled monthlyBuy
Surge2 vCPU · 6 GB · 40 GB NVMe$13.00/mobilled monthlyBuy
Storm6 vCPU · 10 GB · 40 GB NVMe$26.00/mobilled monthlyBuy
Apex6 vCPU · 10 GB · 80 GB NVMe$39.00/mobilled monthlyBuy

Full root SSH access · NVMe storage · DDoS protection · No setup fee

02Before You Start

  • A domain or subdomain with an A record pointing to your server's IP, for example n8n.example.com. DNS changes can take a few minutes.
  • Ports 80 and 443 reachable. If you use the firewall on your server page, allow both; Caddy needs port 80 to get the certificate.
  • Docker: on a fresh Ubuntu 24.04 or Debian 12 server, as root: curl -fsSL https://get.docker.com | sh

03The Compose File

Create a folder /opt/n8n with two files. First docker-compose.yml:

yaml
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    environment:
      - N8N_HOST=n8n.example.com
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.example.com/
      - GENERIC_TIMEZONE=Europe/Berlin
      - TZ=Europe/Berlin
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
    volumes:
      - n8n_data:/home/node/.n8n
    expose:
      - "5678"

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data

volumes:
  n8n_data:
  caddy_data:

Then the Caddyfile:

shell
n8n.example.com {
    reverse_proxy n8n:5678
}

Replace n8n.example.com and the time zone with yours, then start it:

bash
cd /opt/n8n
docker compose up -d
docker compose logs -f

After a few seconds Caddy has the certificate. Open https://n8n.example.com and create the owner account; the first account you create is the admin.

04Settings That Matter

WEBHOOK_URL

makes n8n show the public address in Webhook nodes. Without it, they show localhost and outside services can't reach them.

GENERIC_TIMEZONE

is the zone Schedule Triggers run in. Without it, "every day at 9:00" runs in the container's default time.

n8n only behind Caddy

The compose file exposes port 5678 to Caddy only, not to the internet, so everything goes over HTTPS.

The encryption key

n8n creates one in the data volume and uses it to encrypt saved credentials. Copy it from /home/node/.n8n/config inside the volume and keep it safe.

05Updates and Backups

Update:

bash
cd /opt/n8n
docker compose pull
docker compose up -d

Read the release notes before major versions; workflows occasionally need changes.

Back up the data volume (workflows, credentials, execution history in SQLite):

bash
docker run --rm -v n8n_n8n_data:/data -v /root:/backup alpine \
  tar czf /backup/n8n-$(date +%F).tar.gz -C /data .

Docker names the volume after the folder, so it's n8n_n8n_data for /opt/n8n; docker volume ls shows the exact name. Copy the archive off the server: we don't make backups for you. For a busy instance, switch n8n to Postgres; the n8n docs describe the variables.

06Keep It Safe

  • Strong owner password and two-factor login in n8n's personal settings.
  • SSH only from your IP, with the firewall on your server page.
  • Watch what workflows can reach. An Execute Command or Code node runs with the container's rights; only give n8n accounts to people you trust.

2 GB runs n8n with a handful of workflows. Take 6 GB for many workflows, AI nodes or large files.

  • self host n8n
  • n8n vps
  • n8n docker compose
  • n8n hosting
  • install n8n ubuntu
  • n8n self hosted https

Keep reading

All articles