Skip to content
SelfHostBR, home page
Guide

How to install n8n on a VPS with Docker Compose

Install n8n on a Linux VPS with Docker Compose, Traefik and automatic HTTPS (Let's Encrypt), plus backups, updates and how much memory to reserve.

MMarlon Published on 7 min read
On this page

This guide gives you two containers: n8n, and Traefik, which handles the HTTPS certificate (Let’s Encrypt) and routing. It follows the official n8n documentation.

Self-hosting takes some comfort with servers: you are responsible for updates, backups and security of the instance. If you would rather not run a server at all, see n8n Cloud vs self-hosting.

Before you start

  • A Linux VPS with root or sudo access. Not sure what size to get? Read the n8n RAM and CPU requirements or use the VPS calculator.
  • A domain where you can create a DNS record.
  • Ports 80 and 443 open in the VPS firewall.

Install Docker and Docker Compose

Follow the official Docker instructions for your distribution, then check:

docker --version
docker compose version

To run Docker without sudo, add your user to the docker group (sudo usermod -aG docker ${USER}) and open a new session.

Point a subdomain at the VPS

Create an A record named n8n (or whatever you prefer) pointing to the VPS IP address. n8n will answer at https://n8n.yourdomain.com.

Create the project folder and the .env file

mkdir n8n-compose && cd n8n-compose
mkdir local-files

Create the .env file:

DOMAIN_NAME=yourdomain.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/Berlin
SSL_EMAIL=[email protected]

GENERIC_TIMEZONE sets the timezone used by the Cron and other scheduling nodes; use your own from the tz database list. Without it, n8n falls back to New York time.

Create the compose.yaml

Use the file from the official documentation. The key points:

  • The traefik service listens on ports 80 and 443, redirects HTTP to HTTPS and requests the certificate using SSL_EMAIL.
  • The n8n service publishes port 5678 only on 127.0.0.1, so outside traffic goes through Traefik.
  • The n8n_data volume (at /home/node/.n8n) holds the SQLite database and the encryption key; traefik_data holds the certificates; the ./local-files folder is mounted at /files.
  • The N8N_WEBHOOK_URL variable exists from n8n 2.30.0. On earlier versions, use WEBHOOK_URL.

Use the stable tag, not latest. The latest tag can point to a beta release. In production, change the image to n8nio/n8n:stable or pin a version such as n8nio/n8n:2.43.6.

The official example also sets --api.insecure=true on Traefik, which turns on the Traefik dashboard without a password. It is not exposed because port 8080 is not published, but if you don’t use the dashboard you can delete that line.

Start the containers

sudo docker compose up -d

On the first start, the database and the certificate take about 20 seconds to be ready. Then open https://n8n.yourdomain.com and create the administrator account. To stop everything: sudo docker compose stop.

After it is running

  • Backups: copy the n8n_data volume regularly. Without the encryption key stored in it, saved credentials cannot be read. The steps are in n8n backup.
  • Updates: n8n ships a new version almost every week. Watch the minimum safe version page and update with docker compose pull && docker compose up -d (details in how to update n8n).
  • Database: the default is SQLite. For higher volume or queue mode, use PostgreSQL: see n8n with Docker Compose and PostgreSQL.

How much memory to reserve

With a simple workflow (Webhook → Edit Fields → Respond to Webhook), n8n idles at around 450 to 550 MiB and stays in that range while answering dozens of calls per second, on 1 GB/1 vCPU as well as on 2 GB/2 vCPUs. Traefik uses 20 to 30 MiB. Workflows with AI, large files or heavy use of the Code node use a lot more (see what memory use depends on).

In practice, 1 GB free for n8n covers light personal use; for production, prefer a VPS with 2 GB or more. The n8n and Traefik images take a little over 1 GB of disk; set aside about 5 GB for data, logs and updates.

To keep n8n from taking over the whole VPS, limit the container in the n8n service:

    deploy:
      resources:
        limits:
          memory: 1g
          cpus: "1"

Optional: DNS challenge certificate (Cloudflare)

If the server cannot accept connections on port 443 while the certificate is issued, replace the two mytlschallenge lines with:

      - "--certificatesresolvers.mytlschallenge.acme.dnschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.dnschallenge.provider=cloudflare"

Also pass CF_DNS_API_TOKEN in Traefik’s environment:, using a Cloudflare token with only DNS Edit permission on your zone. Traefik creates and removes the _acme-challenge TXT record by itself.

Where to run it

For current plans and prices, see how much it costs to host n8n. One example is Hostinger KVM 2 (2 vCPU, 8 GB): see the plan ↗.

Frequently asked questions

How much RAM does n8n need on a VPS?

With a simple workflow, n8n idles at around 450 to 550 MiB, and Traefik uses 20 to 30 MiB. 1 GB free is enough for light personal use; for production, prefer a VPS with 2 GB or more. The images take a little over 1 GB of disk.

Should I use the n8nio/n8n:latest image?

Not in production. The latest tag can point to a beta release. Use n8nio/n8n:stable or pin a specific version.

How do I update n8n installed with Docker Compose?

Back up the n8n_data volume, then run docker compose pull followed by docker compose up -d in the project folder.

What do I need to keep in the n8n backup?

The n8n_data volume, which holds the SQLite database and the encryption key. Without that key, saved credentials cannot be read.

M

Written by

Marlon

I like automation and write here what I learn building automations with n8n. Spotted a mistake or an outdated detail? Let me know.

Keep reading