Self-hosting n8n with Docker takes a small Linux server, a domain name and the commands below. The set-up follows n8n's own example, which runs n8n behind Caddy, a web server that creates and renews the HTTPS certificate.
This guide follows that example step by step, with two changes taken from n8n's and Docker's documentation. It then adds a backup you can restore and an update you can undo.

Who this is for
- you have a small Linux server, or are about to rent one, and want n8n on your own domain
- you are comfortable typing commands over SSH
- you want backups and updates sorted from the first day
Not for you if you would rather not run a server at all: see n8n Cloud or self-hosted.
Key numbers
- 2.45.4 version the stable n8n version named in n8n's documentation on 27 October 2026 Official page,
- 443 port HTTPS, served by Caddy; n8n itself listens on port 5678 inside the server Official page,
- 60 seconds how long a task waits for a task runner by default before n8n reports a timeout Official page,
What you are building
Three containers run on one server. Caddy answers on ports 80 and 443 and passes requests to n8n. The n8n container keeps its database, settings and encryption key in a Docker volume called n8n_data. A task runner runs your Code nodes.
- Browser and webhooks (https://n8n.your-domain.com): connects to Caddy (HTTPS).
- Caddy (HTTPS on 443, automatic certificate): connects to n8n (forwards to n8n:5678).
- n8n (port 5678, data in n8n_data): connects both ways with Task runner (tasks).
- Task runner (runs Code node tasks)
Try it on your own computer first
With Docker installed on your computer, n8n's documentation starts it with two commands. Open http://localhost:5678 afterwards and click through a workflow before you rent anything:
bash
docker volume create n8n_data
docker run -it --rm --name n8n -p 5678:5678 \
-e GENERIC_TIMEZONE="Europe/London" -e TZ="Europe/London" \
-v n8n_data:/home/node/.n8n n8nio/n8nWhat you will need
- a Linux server running Ubuntu 24.04 or 22.04 LTS, two of the versions Docker supports
- at least 2 GB of memory; our n8n sizing guide explains why 4 GB suits most small teams
- a domain name, with a subdomain such as n8n.example.com pointed at the server's IP address (an A record)
- SSH access as a user with sudo rights, not as root, as n8n's own server tutorial advises
| Plan | Price | New-customer offer | Link |
|---|---|---|---|
| Hostinger KVM 1 1 vCPU, 4 GB | $6.49/month 24-month term, paid up front; Black Friday first-term price, then $11.99 checked 25 Oct 2026 | Black Friday prices on VPS plans and AI automation apps, for the first subscription term only checked 30 Oct 2026 | Visit |
| DigitalOcean Basic Droplet, 2 vCPUs, 4 GiB 2 vCPU, 4 GB | $24/month billed per second (60-second minimum), capped at this monthly price · VAT not stated checked 25 Oct 2026 | New accounts get a $5 credit that lasts 90 days and covers every product except SaaS add-ons checked 29 Oct 2026 | Visit |
| Kamatera Cloud server Type B (General Purpose), 2 cores, 4 GB 2 vCPU, 4 GB | $39/month monthly, no long-term contract · VAT not stated checked 25 Oct 2026 | A 30-day trial of one cloud server in a configuration worth up to $100 checked 29 Oct 2026 | Visit |
| UpCloud Starter, 2 CPU cores, 4 GB 2 vCPU, 4 GB | €12/month billed by the starting hour, at most 28 days a month; no minimum term checked 25 Oct 2026 | No offer | Visit |
| Liquid Web Cloud VPS (General), 2 vCPUs, 4 GB 2 vCPU, 4 GB | $17/month monthly · VAT not stated checked 25 Oct 2026 | No offer | Visit |
Some of the lowest prices need a long term paid in advance; the term and any renewal price are under each price.
Step 1: prepare the server
Log in as root once to create your own user with sudo rights, then log in again as that user. Bring the system up to date and open only SSH, HTTP and HTTPS in the firewall:
bash
adduser n8nadmin
usermod -aG sudo n8nadmin
# log out, then log in again as n8nadmin
sudo apt update && sudo apt upgrade -y
sudo ufw allow 22
sudo ufw allow 80
sudo ufw allow 443
sudo ufw enableDocker's documentation warns that ports Docker publishes are open on every address of the server, past ufw's rules. That is why the third step keeps n8n's own port on the server itself.
Step 2: install Docker
Docker's documentation installs Docker Engine and the Compose plugin from Docker's own package repository:
bash
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
docker compose versionStep 3: start n8n with Caddy and HTTPS
n8n keeps a ready-made set of files for this in its n8n-hosting repository, under the MIT licence. Fetch it and create the two volumes its Compose file expects:
bash
git clone https://github.com/n8n-io/n8n-hosting.git
cd n8n-hosting/docker-caddy
sudo docker volume create caddy_data
sudo docker volume create n8n_dataEdit the .env file in that folder. Set the n8n version, the folder's own path, your domain, a time zone and a long random token for the task runner, which openssl rand -hex 32 can make:
.env
N8N_VERSION=2.45.4
DATA_FOLDER=/home/n8nadmin/n8n-hosting/docker-caddy
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/London
SSL_EMAIL=you@example.com
RUNNERS_AUTH_TOKEN=paste-a-long-random-string-hereThen put your full address on the first line of caddy_config/Caddyfile:
Caddyfile
n8n.example.com {
reverse_proxy n8n:5678 {
flush_interval -1
}
}Two changes to n8n's example
Make both in docker-compose.yml before the first start. Each comes from n8n's or Docker's own documentation:
- under the n8n service, change the ports line from
5678:5678to127.0.0.1:5678:5678, as n8n's other Compose file does; Caddy still reaches n8n over Docker's own network - change
WEBHOOK_URLtoN8N_WEBHOOK_URL, the name n8n uses from version 2.30.0; the old name is deprecated from 2.35.0
Start the three containers and check that they run:
bash
sudo docker compose up -d
sudo docker compose ps
sudo docker compose logs -f n8nOpen https://n8n.example.com and create the owner account straight away. Until you do, the first person to open the address can set it up.
Step 4: back up, and restore once
By n8n's documentation, the n8n_data volume holds n8n's SQLite database and its encryption key. Back up the whole volume, and also export workflows and credentials with n8n's own commands:
bash
cd ~/n8n-hosting/docker-caddy
sudo docker compose exec -u node n8n n8n export:workflow --backup --output=/home/node/.n8n/backups/workflows/
sudo docker compose exec -u node n8n n8n export:credentials --backup --output=/home/node/.n8n/backups/credentials/
sudo docker compose stop n8n
sudo docker run --rm -v n8n_data:/data -v "$PWD":/backup ubuntu \
tar czf /backup/n8n_data-$(date +%F).tar.gz -C /data .
sudo docker compose start n8nThe archive command follows the volume backup pattern in Docker's documentation. Copy each archive off the server, and run the commands from a daily cron job.
n8n's backup guide is clear about the key: restored credentials can only be read with the same encryption key. Because the volume holds that key, a full volume archive restores both.
Restore one archive at least once, on a spare server billed by the hour, so you know the backup works. On a fresh server set up as in Steps 1 to 3, before the first start:
bash
sudo docker volume create n8n_data
sudo docker run --rm -v n8n_data:/data -v "$PWD":/backup ubuntu \
tar xzf /backup/n8n_data-2026-10-27.tar.gz -C /data
sudo docker compose up -dStep 5: update safely, and roll back if needed
n8n's update guide asks you to update at least once a month and to read the release notes for breaking changes first. Back up as in Step 4, set the new version in .env, then run n8n's update commands:
bash
sudo docker compose pull
sudo docker compose down
sudo docker compose up -dTo go back, set the old version in .env again and restore the archive you took just before the update. According to n8n's documentation, database changes may need undoing before a downgrade, and that archive does it:
bash
sudo docker compose down
# this replaces everything in n8n_data with the archive
sudo docker run --rm -v n8n_data:/data -v "$PWD":/backup ubuntu \
sh -c "rm -rf /data/* /data/.[!.]* ; tar xzf /backup/n8n_data-2026-10-27.tar.gz -C /data"
sudo docker compose up -dCheck that it works
- the address opens over HTTPS, and plain HTTP sends you there
sudo docker compose pslists caddy, n8n and n8n-runner as running- a test workflow with a Webhook node shows a production address that starts with your https domain
- calling that address with curl starts the workflow, and the run appears under Executions
- a Code node runs without a timeout, which shows the task runner is connected
Common errors and their fixes
- "Task request timed out after 60 seconds": a task waited for a runner for the default 60 seconds. Check that the n8n-runner container runs and that both containers use the same RUNNERS_AUTH_TOKEN
- webhook addresses show http or localhost: set N8N_WEBHOOK_URL to your https address and restart
- the address does not open: n8n's tutorial points to the DNS record and the firewall, with ports 80 and 443 open
- saved credentials cannot be read after a restore: the encryption key differs, so restore the whole n8n_data volume, not only the exports
What it costs per month
The server is almost the whole bill. n8n's Community edition, Docker and Caddy cost nothing, and a domain name adds a small yearly fee. Our comparison of n8n Cloud and self-hosting prices both for three example workloads.
How we checked
We followed n8n's documentation and its n8n-hosting repository, Docker's install and storage guides and Ubuntu's firewall guide, all read on 27 October 2026.
Our own measurements will be added here, with their dates, when our test bench runs them.
Mistakes to avoid
Publishing n8n's port 5678 on every address
Instead: Bind it to 127.0.0.1; Caddy reaches n8n inside Docker.
Leaving the runner token at its example value
Instead: Set RUNNERS_AUTH_TOKEN to a long random string.
Backing up the exports but not the volume
Instead: The volume holds the database and the encryption key.
Updating without a fresh backup
Instead: Back up first: going back may need the old database.
Other questions
How do I install n8n with Docker?
Install Docker, fetch n8n's n8n-hosting repository, fill in its .env file and run docker compose up -d. The steps above add HTTPS, backups and safe updates.
How do I update n8n in Docker?
Back up first and set the new version in .env. Then run docker compose pull, docker compose down and docker compose up -d, as n8n's documentation shows.
Can I run n8n with Docker on my own computer?
Yes. n8n's documentation starts it with docker volume create n8n_data and one docker run command; then you open http://localhost:5678.
Does n8n need Postgres?
No: it uses SQLite by default. n8n's repository has a Postgres version of these files, and queue mode needs Postgres.
Sources and test notes
- n8n-hosting repository: docker-caddy (MIT licence), read
- n8n-hosting repository: withPostgres, read
- n8n documentation: deploy to DigitalOcean (Caddy tutorial), read
- n8n documentation: use Docker Compose (Traefik example), read
- n8n documentation: install with Docker, read
- n8n documentation: update n8n, read
- n8n documentation: back up and restore, read
- n8n documentation: use the command line, read
- n8n documentation: task runner settings, read
- n8n documentation: webhook URLs behind a reverse proxy, read
- n8n documentation: OEM prerequisites (downgrades), read
- Docker: install Docker Engine on Ubuntu, read
- Docker: volumes (back up a volume), read
- Docker: port publishing, read
- Ubuntu Server: firewalls (ufw), read
Every page read on 27 October 2026. The Compose files are n8n's own MIT-licensed examples, with the two changes named above.