How to Deploy n8n on an Ubuntu VPS with Docker
A production n8n install on Ubuntu 24.04 using Docker Compose, PostgreSQL and Caddy for automatic TLS — with the encryption key, webhook URL and backup steps most quickstarts leave out.
Run self-hosted n8n as infrastructure rather than a hobby project — Postgres storage, TLS, encryption key handling, host hardening and backups that include the things a database dump misses.
The n8n quickstart gets you a running instance in five minutes. It also leaves you with SQLite, no TLS, a default encryption key handling story and a port open to the internet — all of which are fine for an evening of experimenting and none of which are fine once a workflow holds real API credentials.
This path replaces each of those defaults, in the order that matters: storage and TLS first, then the host, then backups.
The recurring theme is the encryption key. n8n encrypts stored credentials with it, it is not included in a database dump, and losing it means re-entering every integration by hand. All three articles come back to that.
Read in order. Ticking a lesson stores your progress in this browser only.
A production n8n install on Ubuntu 24.04 using Docker Compose, PostgreSQL and Caddy for automatic TLS — with the encryption key, webhook URL and backup steps most quickstarts leave out.
n8n, PostgreSQL and Caddy, with the environment variables that matter.
SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.
Especially the Docker and UFW interaction — n8n's port must not be public.
A nightly backup for a self-hosted Docker host: database dumps taken with the right tools, file volumes snapshotted with restic, a systemd timer to run it, and a restore test that proves it works.
A database dump alone is not a complete n8n backup.
A production n8n install on Ubuntu 24.04 using Docker Compose, PostgreSQL and Caddy for automatic TLS — with the encryption key, webhook URL and backup steps most quickstarts leave out.
SSH hardening, a default-deny firewall, and the fix for the problem that catches almost everyone — Docker publishing container ports straight past UFW into the public internet.
A nightly backup for a self-hosted Docker host: database dumps taken with the right tools, file volumes snapshotted with restic, a systemd timer to run it, and a restore test that proves it works.