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:
- The database - workflows, executions, settings.
- The
/home/node/.n8nvolume - files and local data. 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.
- n8n: A Complete Practical Guide to Workflow AutomationGuide
- Triggers and Webhooks in n8n: How a Workflow StartsTrigger types in n8n and working with webhooks: test URL versus production URL, why a webhook never arrives, responding to the caller, schedules and timezones, and securing a public endpoint.
- Data and Expressions in n8n: Items, $json and Why a Node Runs Many TimesHow data works in n8n: an array of items rather than an object, $json and node expressions, reaching earlier nodes, nested JSON, merging and splitting branches, and the usual empty-data mistakes.
- Error Handling in n8n: Retries, Error Workflows and Reliable AutomationHow to make an n8n workflow durable: node-level error settings, retries and timeouts, a dedicated error workflow for alerts, idempotency under re-runs, and why automation usually fails silently.
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
"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."