How to install n8n on a VPS with Docker and HTTPS

n8n is a workflow automation platform: it connects APIs, spreadsheets, CRMs, bots and AI models without coding everything from scratch. Running n8n on your own VPS gives you unlimited executions, full control of your data and a fixed cost. In this tutorial we will install it with Docker Compose, behind Caddy, which issues and renews the Let's Encrypt HTTPS certificate on its own.

Before you start

You need Docker and Docker Compose installed (see the tutorial Installing Docker and Docker Compose) and an address for n8n:

  • Your own domain (recommended): create a DNS A record, for example n8n.yourdomain.com, pointing to the server IP;
  • No domain: use the free sslip.io service, replacing the dots in the IP with hyphens. For IP 203.0.113.24, the address is 203-0-113-24.sslip.io.
Ports 80 and 443 must be free and allowed in the firewall, if one is active.

Creating the files

Create the project folder and the .env file with your address (replace it with yours):

# mkdir -p /root/n8n && cd /root/n8n
# echo "DOMINIO=n8n.yourdomain.com" > .env
# nano Caddyfile
In the Caddyfile, paste the content below. It publishes n8n at your address with automatic HTTPS:

{$DOMINIO} {
    reverse_proxy n8n:5678
}
Next, create compose.yaml:

# nano compose.yaml
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    environment:
      - N8N_HOST=${DOMINIO}
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://${DOMINIO}/
      - GENERIC_TIMEZONE=America/Sao_Paulo
      - TZ=America/Sao_Paulo
    volumes:
      - n8n_data:/home/node/.n8n

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    environment:
      - DOMINIO=${DOMINIO}
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data

volumes:
  n8n_data:
  caddy_data:
Adjust the time zone (GENERIC_TIMEZONE and TZ) if needed. n8n data lives in the n8n_data volume and certificates in caddy_data, so they survive updates and restarts.

Starting n8n

# docker compose up -d
In about a minute Caddy gets the certificate and n8n is available at https://your-address.

Important: open the address right away and create the owner account. The first access defines the n8n owner, and bots often visit new HTTPS addresses within seconds of the certificate being issued.

Updating n8n

n8n releases new versions often, including security fixes. To update, from inside /root/n8n:

# docker compose pull
# docker compose up -d
Your workflows and credentials stay saved in the volume. To follow the logs, use docker compose logs -f n8n.
If you have any difficulties, open a support ticket: Open ticket