Skip to main content
Find my setup
Language: English

Self-host n8n with Docker: HTTPS, backups and safe updates, step by step

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.

Rows of colourful shipping containers in a port yard, seen from directly above, with a container handler at the side
Docker packs n8n, its web server and its task runner into separate containers. Photo: Ollie Craig, Pexels.

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.

Caddy in front of n8n, as in n8n's own example Only Caddy is reachable from the internet; the rest talk over Docker's network.
Caddy in front of n8n, as in n8n's own exampleBrowser and webhooks https://n8n.your-domain.com HTTPS Caddy HTTPS on 443, automaticcertificate forwards ton8n:5678 n8n port 5678, data in n8n_data tasks Task runner runs Code node tasks
  1. Browser and webhooks (https://n8n.your-domain.com): connects to Caddy (HTTPS).
  2. Caddy (HTTPS on 443, automatic certificate): connects to n8n (forwards to n8n:5678).
  3. n8n (port 5678, data in n8n_data): connects both ways with Task runner (tasks).
  4. 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/n8n

What 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
Servers with 4 GB of memory. Prices checked on 25 Oct 2026.
PlanPriceNew-customer offerLink
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 enable

Docker'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 version

Step 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_data

Edit 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-here

Then 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:5678 to 127.0.0.1:5678:5678, as n8n's other Compose file does; Caddy still reaches n8n over Docker's own network
  • change WEBHOOK_URL to N8N_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 n8n

Open 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 n8n

The 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 -d

Step 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 -d

To 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 -d

Check that it works

  • the address opens over HTTPS, and plain HTTP sends you there
  • sudo docker compose ps lists 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

Every page read on 27 October 2026. The Compose files are n8n's own MIT-licensed examples, with the two changes named above.

Back to n8n hosting