Skip to content
PD
n8n

Installing n8n with Docker: Self-Hosting on Your Own Server

How to stand up n8n on your own server with Docker: compose file, data volume, encryption key, HTTPS and webhooks behind a reverse proxy, moving to PostgreSQL, and what to back up so you never lose credentials.

All articles in the guide n8n · 18

The reason to self-host n8n is not saving money but control: your data never reaches a third party, and per-operation billing disappears. The price is that you become the service’s administrator, and a few things are much easier to get right on day one.

The minimal run

For a first look, one container with a mounted volume is enough:

docker run -d --name n8n \
  -p 5678:5678 \
  -v n8n_data:/home/node/.n8n \
  docker.n8n.io/n8nio/n8n

The volume is not optional. Without it every workflow and credential lives inside the container and disappears the first time you pull a new image.

That is fine for kicking the tyres. Anything lasting longer than a couple of days wants a compose file and a few variables.

Set these before your first workflow

N8N_ENCRYPTION_KEY - the important one. It encrypts your credentials. If n8n generates it for you and you later lose the volume, restoring the database gives you workflows with not a single working credential. Set it explicitly and store it wherever your other secrets live.

WEBHOOK_URL - the public address of your n8n. Without it the UI shows webhook URLs as localhost:5678, and no external service can reach you.

GENERIC_TIMEZONE - the timezone for schedules. It defaults to UTC, which is exactly why the “daily 9am report” arrives at noon.

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    ports:
      - '127.0.0.1:5678:5678'
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - WEBHOOK_URL=https://n8n.example.com/
      - GENERIC_TIMEZONE=Europe/Berlin
    volumes:
      - n8n_data:/home/node/.n8n
volumes:
  n8n_data:

Note 127.0.0.1:5678 - the container listens locally only, and the proxy exposes it. Publishing the port straight to the internet is not a good idea.

HTTPS and a reverse proxy

Without a domain and a certificate, self-hosted n8n stays a toy: payment providers, GitHub and most SaaS will not send a webhook to plain http or to an address with a port in it.

A reverse proxy (Caddy is simplest, nginx more familiar) handles that: it terminates TLS and proxies to 5678. One detail people trip on: the proxy must not cut long requests short or drop the connection on timeout - a workflow can run for minutes, and an aggressive proxy timeout will sever it halfway.

SQLite or PostgreSQL

n8n runs on SQLite by default. For personal use and a dozen workflows that is plenty.

Move to PostgreSQL when execution volume grows and history bloats, when you need concurrent runs without locking, or when n8n stops being a personal tool and becomes part of a real process. Migrating later is possible but it is its own operation - if you already know the project is serious, start on Postgres.

Separate hygiene item: prune execution history. By default it accumulates, and on busy workflows the database grows faster than you expect. Configure automatic deletion of old executions, or one day the disk fills up because of run logs rather than data.

Updates

Updating is an image swap: stop, docker compose pull, bring it back up. Data in the volume survives.

Two habits worth keeping: do not update blind on an active project (check the changelog before a major version - nodes change), and have a fresh backup before the update, not after.

What to back up

Three things, all mandatory:

  1. The database - workflows, executions, settings.
  2. The /home/node/.n8n volume - files and local data.
  3. N8N_ENCRYPTION_KEY - without it the first two give you a system with no access to anything.

The third is the classic restore-day mistake. A backup without the key looks complete right up until you try to run the first workflow.

When one container is not enough

Once you have many workflows firing at the same time, a single process becomes the constraint. That is when n8n gets deployed in queue mode: a main process, Redis for the queue, and several workers sharing executions between them.

That is real infrastructure, and it is worth taking on when load demands it rather than in advance. The tell that it is time: executions start queuing behind each other, and timeout errors appear in logic you never touched.

FAQ

What do I need to self-host n8n?

A VPS with 2 GB of RAM to start, Docker, a domain and a reverse proxy with HTTPS. The domain is not cosmetic: webhooks must arrive at a public address, and external services almost always require https.

What must I back up in a self-hosted n8n?

Three things: the database, the n8n data volume, and the N8N_ENCRYPTION_KEY variable. The key is critical - without it stored credentials cannot be decrypted, and a restore gives you workflows with no working access.

More on this topic

Done for you

I will build the automation in n8n or in code

Leads, sheets, CRM and Telegram connected, so nobody moves data by hand again.

from $300 · 3 to 7 days

Similar caseBAS Script License Issuing Automated on MakeA Make scenario that turns one Telegram message into a full licence handover: generated login and password, a licence for the requested term, FingerprintSwitcher Business enabled, and a row written to Google Sheets.

"Thanks to Pavel, the task is done. Always reachable, gave me detailed instructions and a guide, I will come back and I recommend him to everyone."

MarkBorisov · KworkTranslated from Russian