1. Point a Subdomain at the Server
At your DNS provider, add an A record for n8n.example.com with your server's IP address. Then install Docker by following How to run Docker and Docker Compose on a VPS.
2. Write the Compose File
mkdir -p ~/n8n && cd ~/n8n nano compose.yaml
services:
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678" # only reachable through Nginx
environment:
N8N_HOST: "n8n.example.com"
N8N_PROTOCOL: "https"
N8N_PORT: "5678"
WEBHOOK_URL: "https://n8n.example.com/"
GENERIC_TIMEZONE: "America/New_York"
TZ: "America/New_York"
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
name: n8n_datadocker compose up -d docker compose logs -f # wait for "Editor is now accessible", then Ctrl+C
3. Put Nginx and HTTPS in Front
Follow steps 2 to 4 of How to host a website on a VPS with n8n.example.com as the name, using the reverse proxy block from its step 6 with port 5678. n8n's editor uses WebSockets, so keep the Upgrade and Connection headers from that block:
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}Open https://n8n.example.com and create the owner account straight away: until you do, whoever opens the page first can create it.
4. Back Up the Data
docker run --rm -v n8n_data:/data -v "$PWD":/backup alpine \ tar -czf /backup/n8n-$(date +%F).tar.gz -C /data .
Copy the archive off the server, or include ~/n8n in a nightly Borg backup. The archive contains the key that decrypts your saved credentials, so store it as carefully as the credentials themselves.
5. Update
cd ~/n8n docker compose pull && docker compose up -d
Read n8n's release notes before a major version, and take a backup first: database changes are applied when the new version starts.