[ PLAYBOOK · 06 ] · MAY 9, 2026 · 3 min
Self-host n8n on a Hetzner CX23 in one afternoon.
A two-hour stack: Docker Compose with Postgres 16 and Caddy. The risk is not the setup; it is the retention defaults you accept without thinking and the backups you forget to test.
The take
A self-hosted n8n on a Hetzner CX23 with Postgres and Caddy is a two-hour job for an engineer who has touched Docker before. The risk is not the setup. The risk is the retention defaults you accept without reading and the backups you never restore-test.
Why this stack
The Hetzner CX23 is around 4 euros per month for two vCPUs, four gigabytes of RAM, and forty gigabytes of disk. Most SMB workflow loads fit inside that envelope without strain. A common reference architecture, mirrored in n8n's hosting examples, is the one we use here: n8n in one container, Postgres 16 in a second, Caddy as the reverse proxy in a third. Caddy gives you free TLS through Let's Encrypt with no certbot ceremony. Postgres handles concurrent executions; the SQLite default does not.
When this breaks
Single-node n8n breaks when you need redundancy or queue mode for high-concurrency executions. SQLite-only deployments break under any meaningful load. Loss of the n8n encryption key breaks every credential in your vault, and there is no recovery path. If you cannot commit to off-instance backups and a monthly update window, you do not actually own this. You are renting an outage.
What to do this afternoon
- Provision a CX23 (Ubuntu 24.04 LTS) in Hetzner Cloud. Five minutes.
- Point a subdomain at the public IP. Wait for DNS.
- Install Docker Engine and the Compose plugin.
- Generate three secrets: a Postgres password, an n8n encryption key, and a basic-auth password. Store the encryption key in a password manager you back up. Without it, every saved credential becomes garbage.
- Use the official n8n Docker Compose file. In the n8n service, set
EXECUTIONS_DATA_PRUNE=trueandEXECUTIONS_DATA_MAX_AGE=168to keep one week of execution history. Recent n8n releases enable pruning by default with a 14-day window; the explicit settings tighten retention and survive future default changes. docker compose up -d. Caddy negotiates the certificate on first request.- Install restic. Back up the Postgres volume nightly to a Hetzner Storage Box or any off-instance store. Run a restore test before you trust the schedule.
- Calendar a monthly update window: backup, then
docker compose pull && docker compose up -d.