corevia_cloud Get started
← Blog

How to self-host n8n on a VPS in 10 minutes

n8n is an open-source automation tool, similar to Zapier or Make, that you can run on your own server. Self-hosting means your workflows, credentials and execution history stay on a machine you control, and you are not limited by per-task pricing.

This guide takes you from a fresh Ubuntu server to n8n running at https://n8n.example.com with a real HTTPS certificate. If your domain is ready, the hands-on part takes about ten minutes.

What you need

  • A VPS running Ubuntu 24.04 (22.04 works too) with root SSH access and a public IPv4 address.
  • A domain or subdomain you control, for example n8n.example.com.
  • A terminal on your computer: Terminal on macOS and Linux, PowerShell or Windows Terminal on Windows.

Throughout this guide, replace n8n.example.com with your own subdomain and 203.0.113.10 with your server's IP address.

Step 1. Point your domain at the server

In your DNS provider's panel, create an A record:

  • Name: n8n (or whatever subdomain you want)
  • Value: your server's IPv4 address

DNS changes can take a few minutes to become visible. You can check from your computer:

nslookup n8n.example.com

When the answer shows your server's IP, you are ready for HTTPS.

Step 2. Connect and update the server

ssh root@203.0.113.10
apt update && apt upgrade -y

Step 3. Install Docker

Docker's official install script adds Docker Engine and the Compose plugin:

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
docker compose version

The last command should print a version number. If it does, Docker is installed.

Step 4. Open only the ports you need

ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Port 80 is needed so the HTTPS certificate can be issued; port 443 is where n8n will be served.

Docker publishes container ports around ufw. That is why, below, only the Caddy web server publishes ports 80 and 443, and n8n itself is not published to the internet at all.

Step 5. Create the project files

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

Create a file called .env with your settings. The encryption key protects the credentials n8n stores, so generate a random one and keep a copy somewhere safe:

cat > .env <<EOF
N8N_HOST=n8n.example.com
GENERIC_TIMEZONE=Europe/Berlin
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
EOF
chmod 600 .env

Now create docker-compose.yml:

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    environment:
      - N8N_HOST=${N8N_HOST}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://${N8N_HOST}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${GENERIC_TIMEZONE}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    volumes:
      - n8n_data:/home/node/.n8n

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

volumes:
  n8n_data:
  caddy_data:
  caddy_config:

And a Caddyfile for the web server. Caddy requests and renews the HTTPS certificate automatically:

n8n.example.com {
    reverse_proxy n8n:5678
}

Step 6. Start n8n

docker compose up -d
docker compose logs -f

Wait until the logs show that n8n is ready and Caddy has obtained a certificate, then press Ctrl+C to stop following the logs (the containers keep running).

Open https://n8n.example.com in your browser. On the first visit n8n asks you to create the owner account. Do it right away: until you do, anyone who opens the address could claim it.

Keeping it healthy

Updates. New n8n versions come out often. To update:

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

Read the n8n release notes before big version jumps, and take a backup first.

Backups. Your workflows and credentials live in the n8n_data volume. A simple manual backup:

cd /opt/n8n
docker compose stop n8n
docker run --rm -v n8n_n8n_data:/data -v "$PWD":/backup alpine tar czf /backup/n8n-backup.tar.gz -C /data .
docker compose start n8n

The volume name is the project folder plus the volume name (n8n_n8n_data here); docker volume ls shows the exact name. Copy the archive and your .env file off the server. Without the encryption key from .env, stored credentials cannot be decrypted.

Security basics.

  • Keep the system updated: apt update && apt upgrade -y from time to time, or enable unattended-upgrades.
  • Use SSH keys instead of a password for logging in.
  • Never commit .env to a Git repository.

Common problems

  • The browser shows a certificate error. DNS probably did not point to the server yet when Caddy started. Check with nslookup, then run docker compose restart caddy.
  • Webhooks show localhost URLs. WEBHOOK_URL is missing or wrong in docker-compose.yml. Fix it and run docker compose up -d.
  • "Your n8n server is configured to use a secure cookie" message. You are opening n8n over plain http. Use the https:// address.

Where to go next

Once n8n is running, you can connect it to your CRM, email, Telegram or AI models and let workflows run around the clock, even when your laptop is closed. That is the main reason to self-host on a VPS instead of running n8n on your own computer.

Need a server for this? Corevia Flow Cloud gives you a VPS with root SSH access and a public IPv4. See current plans and prices on the pricing page.

Get started →