How to Self-Host n8n with Docker Compose on Ubuntu 24.04 A developer published a step-by-step guide for self-hosting n8n 2.41.6 on Ubuntu 24.04 using Docker Compose, PostgreSQL 18, an external n8nio/runners task runner, and Caddy for HTTPS. The setup keeps n8n bound to 127.0.0.1:5678 behind Caddy on ports 80 and 443, and warns that Docker-published ports bypass UFW, so a publicly exposed 5678 stays reachable even when UFW denies it. It also notes that n8n 1.0 removed the N8N_BASIC_AUTH variables and that n8n 3.0 supports Docker-based installs only. Originally published by Arct Cloud: How to Self-Host n8n with Docker Compose on Ubuntu 24.04 https://www.arct.cloud/tutorials/self-host-n8n . This article was prepared with AI assistance. Product references were removed and formatting adjusted for this DEV edition. TL;DR: n8nio/runners task runner and PostgreSQL 18, with Caddy in front for HTTPS on ports 80 and 443. 127.0.0.1:5678 only. Docker-published ports bypass UFW, so a public 5678 stays open even when UFW denies it. N8N ENCRYPTION KEY , N8N WEBHOOK URL and N8N PROXY HOPS=1 . WEBHOOK URL in n8n 2.35.0, and n8n 1.0 removed the N8N BASIC AUTH variables. .env . n8n 3.0 supports Docker-based installs only. Applies to: Ubuntu 24.04 LTS · n8n 2.41.6 · PostgreSQL 18 · Caddy 2.11.7 · Docker Compose 5.6.0 · checked October 2026 n8n is a fair-code workflow automation platform that connects apps, APIs and AI models in visual workflows started by webhooks, schedules or other triggers. This tutorial self-hosts n8n 2.41.6 on Ubuntu 24.04 with Docker Compose, PostgreSQL 18, an external task runner and Caddy for HTTPS, then covers updates and backups. A VPS gives your webhooks a public HTTPS address that stays reachable when your own computer is off. docker group. Follow n8n.example.com that points to your server's IP address, for example 203.0.113.10 . Commands run as the sudo user. Replace values written in capitals, such as YOUR DOMAIN , with your own. Four components run on the server. Only Caddy accepts connections from the internet: | Component | Runs as | Port | Reachable from | |---|---|---|---| | Caddy | systemd service on the host | 80, 443 | Internet | | n8n | n8nio/n8n:2.41.6 container | 5678 | 127.0.0.1 only | | Task runner | n8nio/runners:2.41.6 container | none | Compose network | | PostgreSQL | postgres:18 container | 5432 | Compose network | The task runner executes Code node tasks in its own container and connects to n8n's task broker on port 5679. n8n's docs recommend this external mode for production, because internal mode runs user code next to n8n and its stored credentials. The three images are about 620 MB compressed, and n8n deletes execution data older than 14 days by default. n8n's one-line installer at get.n8n.io uses SQLite and serves plain HTTP on port 5678. This tutorial writes the Compose file by hand for a public server. Caddy needs ports 80 and 443 to get a TLS certificate, often called an SSL certificate, and to serve n8n. Allow SSH before you enable UFW, or the current session drops: sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable sudo ufw status Type y if UFW asks to confirm. The output looks similar to this: Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere 80/tcp ALLOW Anywhere 443/tcp ALLOW Anywhere OpenSSH v6 ALLOW Anywhere v6 80/tcp v6 ALLOW Anywhere v6 443/tcp v6 ALLOW Anywhere v6 Do not open 5678. Step 4 publishes n8n on the loopback address, and Caddy reaches it there. Compose reads variables from a .env file in the project directory. Create the directory: mkdir ~/n8n cd ~/n8n Replace YOUR DOMAIN with your subdomain, such as n8n.example.com , and YOUR TIMEZONE with a time zone name, such as Europe/Berlin . Then run the block. It writes the file and generates four random secrets, and umask 077 inside the parentheses makes .env readable only by your user: umask 077 cat .env <