Our n8n instance runs the boring side of LumaDock: it watches WHMCS for new orders, nudges the provisioning queue, posts to Slack when a payment fails twice and files the monthly invoice export where finance expects it. It has lived on a VPS with Docker since 2024. In January I rebuilt it for n8n 2.x from a blank server, mostly because the compose file had grown three years of cruft and I wanted to see what a clean 2026 install looks like. This post is the notes from that: what changed in n8n 2.0 for anyone self-hosting, where the hosted version still makes sense, what the license allows and the smallest stack I'd trust with real work.
What n8n 2.0 changed for self-hosting
2.0 shipped on December 8, 2025 and the current stable is 2.38.5, with 3.0 announced for October 2026. The 2.0 breaking changes list is long, and for someone running n8n on their own server five items on it matter more than the rest.
Task runners run by default. Every Code node now executes in a runner outside the main process, and N8N_RUNNERS_ENABLED is deprecated because there's nothing to enable anymore. The default mode is internal (a child process), and the recommended production mode is external, where a separate n8nio/runners container does the work; Python in the Code node only exists in that external mode now, the old Pyodide implementation is gone. Along with that, $env in Code nodes and expressions is blocked by default (N8N_BLOCK_ENV_ACCESS_IN_NODE=true), and the Execute Command and Local File Trigger nodes are disabled unless you clear NODES_EXCLUDE. Every one of those broke a workflow of mine during the rebuild, and every one of them was right to.
Workflows are published now, where they used to be activated. The toggle in the UI changed, the CLI's update:workflow --active is deprecated in favour of publish:workflow and unpublish:workflow, and external hooks keyed on the old activation event are gone. The Docker tags were renamed too, latest became stable and next became beta, though the old names still resolve. MySQL and MariaDB are no longer an option for n8n's own database, leaving SQLite (with a faster pooled driver) and PostgreSQL 16 to 18. And the one with a date on it: from 3.0 in October, self-hosted n8n is Docker only. The 3.0 breaking changes page says npm and npx installs stop being supported, so anyone still running n8n under pm2 has about a month to move it into a container. Everything else that changed, and the whole self-hosting picture around it, is mapped in the complete n8n VPS self-hosting guide, which I keep updated as the versions move.
n8n Cloud or self-hosted n8n
n8n Cloud bills by execution, meaning one run of a workflow regardless of how many nodes it has or how much data passes through. Self-hosted n8n has no execution meter of any kind; the community edition is free to run under the Sustainable Use License and you pay for the server. Which one wins depends entirely on the shape of your automations. A team with a handful of workflows that fire a few hundred times a month is served well by the hosted tiers and never has to think about Postgres. A team whose workflows poll every minute, or process webhooks from a shop with real traffic, hits the execution count of a hosted plan long before it hits the CPU of a small VPS, and the same is true of a single scheduled job that iterates over thousands of rows.
Data residency is the other reason, and it's a bigger one for European companies than the meter. On your own server the execution data, the credentials and the payloads from every third-party API sit in a database you administer in a region you picked. There is no additional processor in the chain to list in a DPA, which the GDPR notes for self-hosted n8n go into, along with the paperwork that self-hosting doesn't remove. It shortens the list; it doesn't empty it.
The Sustainable Use License...
You can run n8n for your own business, build workflows for clients, modify it and embed it as a backend, all free. You can't host it and charge people for access to it or white-label it inside a product you sell without a commercial agreement with n8n. The full terms are short. n8n calls the model fair-code, which is a different thing from OSI open source, and for a company automating its own operations that distinction changes nothing.
A minimum n8n Docker stack for a VPS
Docker Compose with the image pinned to a version, PostgreSQL 17 in the same compose project, a reverse proxy with TLS in front (Caddy when n8n has the box to itself, nginx when it shares it), N8N_ENCRYPTION_KEY set in a .env file before the first start and copied somewhere off the server, N8N_WEBHOOK_URL and N8N_PROXY_HOPS=1 so webhooks and client IPs come out right, and execution pruning left on with a retention you chose on purpose. That's it. Port 5678 is never published. The complete walk-through with the compose file is the n8n on Ubuntu 24.04 with Docker and Caddy tutorial, and the choice between Caddy and nginx comes down to how many other things share the server; the nginx reverse proxy setup for n8n is the version I use on our multi-app box, with certbot renewing five certificates from one timer. Postgres over SQLite is the other choice in that list, and the SQLite vs PostgreSQL comparison for n8n has the size at which I switched and the export and import commands for doing it later.
A 2 vCPU, 2 GB VPS runs this comfortably for one instance. Ours sits on 4 GB because the WHMCS export workflow builds a large array once a month and I'd rather not tune around it. Queue mode, workers and Redis are a later problem, and one many instances never reach.
Small digression on the pinning. n8n releases a minor version most weeks. Pinning means I read the release notes once a month, pick a version, edit one line and restart, with a database dump taken first. An unpinned stable tag means the next docker compose pull for an unrelated reason drags a schema migration in with it, on a day I didn't choose. Nothing in the 2.x line has bitten me that way, but 1.x did, twice.
Where self-hosted n8n setups fail
Three patterns cover nearly every "help, n8n is down" I've seen from customers this year.
SQLite forever. The default database is fine on day one and by month six it is the largest file on the disk, because pruning reuses space in SQLite and never gives it back. The instance still works; the editor gets slow and the backup script starts copying a 3 GB file every night. Moving is a two hour job with the CLI export and import, and it gets longer every month it's postponed because the file only grows.
No copy of the encryption key. n8n generates one on first start and keeps it in the data volume. People back up the database religiously and never the key, then restore onto a new server and every credential decrypts to garbage. Workflows survive that. Credentials don't, and re-entering forty OAuth connections on a Sunday is the price. The key is one line; put it in .env and in the password manager.
Port 5678 on the internet. A compose file with 5678:5678 published "for testing" that never got removed, so the editor answers unencrypted on the server's IP with the login form exposed, and because Docker's published ports bypass UFW the firewall rule someone added later did nothing. The fix is to bind to 127.0.0.1 or not publish at all and let the proxy reach the container over the compose network. What I don't know yet is how much of this gets caught by the new SSRF protection and security audit features in 2.x, because the customers who hit it weren't running either.
The n8n VPS template with Docker and Caddy
If the stack above is what you want and the twenty minutes of setup isn't, the n8n VPS template deploys it for you: n8n with Docker and Caddy already configured on Ubuntu, chosen as the template while you order, on our own AMD EPYC and NVMe hardware in any of nine locations (London, Frankfurt, Paris, Amsterdam, Helsinki, Bucharest, Warsaw, Madrid or New York), with unmetered bandwidth, no setup fee and a 30 day refund window.
It's a normal VPS underneath with root access, so everything in the tutorials linked above applies to it unchanged, pinning the version and copying the encryption key somewhere safe included. That last one is still on you. It always will be.

