I run n8n on a self-hosted Hetzner VPS and it costs me around €6.50 a month. The n8n cloud plan starts at $20/month and limits your workflow executions. For a freelancer building client automations, self-hosting is an obvious choice — you own your data, your workflows are private, and you're GDPR-compliant by default since the server sits in Germany.
This post walks through exactly how I set it up using Coolify as the deployment layer. I'll also be honest about what went wrong and what I'd do differently — because the tutorials that skip that part are the ones that leave you stuck at 2am.
Why Hetzner + Coolify
Hetzner is a German cloud provider with excellent price-to-performance. Their CX23 server (2 vCPUs, 4GB RAM, 40GB SSD) is more than enough to run n8n plus a few other services, and it costs about €3.56/month. For context, that's the same price as a large coffee in Germany.
Coolify is an open-source self-hosted alternative to platforms like Heroku or Railway. It gives you a clean UI to deploy services, manage domains, handle SSL certificates automatically, and set up a reverse proxy — all without touching Nginx config files manually. It also connects to your GitHub repos and auto-deploys on push, which is what I use for this portfolio site.
The combination means you get a proper deployment platform on cheap European infrastructure. Everything stays in the EU, which matters if you're building automations for clients with GDPR obligations.
Step 1 — Set Up Your Hetzner Server
Go to hetzner.com → Cloud → Create Server. Choose these settings:
- Location: Helsinki (Finland, EU) — or Nuremberg/Falkenstein if you prefer Germany
- Image: Ubuntu 22.04 LTS
- Type: CX23 (4GB RAM) — the CX11 with 2GB is too tight once you add a database
- Networking: Public IPv4 enabled
- SSH Key: Add your public key here — you'll need it to log in
Once created, Hetzner gives you an IP address. Copy it — you'll use it in the next step.
Point your domain at the server
In your DNS provider, create an A record pointing your domain (or subdomain like n8n.yourdomain.de) to that IP address. Also add a wildcard record *.yourdomain.de pointing to the same IP — this lets Coolify handle subdomains for every service you deploy later.
Type: A
Host: n8n
Answer: YOUR_SERVER_IP
TTL: 600
Type: A
Host: *
Answer: YOUR_SERVER_IP
TTL: 600
DNS can take up to an hour to propagate. In practice it's usually 5 minutes.
Step 2 — Install Coolify
SSH into your server, then run the one-line Coolify installer:
ssh root@YOUR_SERVER_IP
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
This installs Docker, Docker Compose, and Coolify itself. It takes about 3-5 minutes. When it finishes, it gives you a URL like http://YOUR_IP:8000 — open that in your browser and create your admin account.
Step 3 — Deploy n8n via Coolify
In Coolify, go to Projects → New Project. Name it something like "n8n". Then inside that project, click + New → Service.
Coolify has n8n in its service catalogue — search for it and select it. You'll see a pre-configured template. Before deploying, set these environment variables:
N8N_HOST=n8n.yourdomain.de
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.yourdomain.de
N8N_ENCRYPTION_KEY=generate-a-random-32-char-string-here
GENERIC_TIMEZONE=Europe/Berlin
The N8N_ENCRYPTION_KEY is important — it encrypts your stored credentials. Generate one with:
openssl rand -hex 16
Then set your domain to https://n8n.yourdomain.de in the Coolify domain field and hit Deploy. Coolify pulls the n8n Docker image, starts the container, configures the reverse proxy, and provisions an SSL certificate. The whole thing takes about 2 minutes.
Step 4 — First Login and Basic Config
Visit https://n8n.yourdomain.de. You'll be greeted with the n8n setup wizard. Create your owner account — use a strong password, this instance is publicly accessible.
A few settings worth changing immediately in n8n Settings:
- User Management: Keep it to just yourself for now unless you're sharing with a team
- Community Nodes: Enable this — some very useful community nodes exist for things Coolify doesn't support natively
- Timezone: Set to Europe/Berlin if you're in Germany — otherwise scheduled workflows run at wrong times
What I'd Do Differently
A few things caught me off guard that the official docs don't emphasise enough.
Use a persistent volume for your data. By default, if Coolify redeploys your n8n container, it can wipe your workflow data. In Coolify's service settings, make sure the data path /home/node/.n8n is mounted to a persistent volume. Coolify calls this "Persistent Storage" in the service configuration. Set it up before you build your first workflow.
The WEBHOOK_URL variable is critical. If you skip it or set it wrong, webhooks from external services (Gmail, Stripe, etc.) won't reach n8n. It must match exactly the domain you're using, including https://.
CX13 is too small. I recommend CX23 (4GB RAM) as the minimum if you plan to run n8n plus a database plus anything else on the same server. At 2GB, you'll hit memory pressure when running complex workflows with large payloads.
Coolify handles restarts automatically — if the n8n container crashes, it restarts it. But there are a few maintenance habits worth building: For reference, here's what this setup costs me per month: Compare that to n8n Cloud's Starter plan at $20/month (~€18) with execution limits, or their Pro plan at $50/month. Self-hosting pays for itself immediately if you're running more than a handful of workflows. The setup takes about 30 minutes if you follow these steps in order. The main things to get right are: persistent storage before you build anything, the correct environment variables especially Once it's running, it genuinely just runs. I've had my instance up for months without touching it. Coolify handles SSL renewal, container restarts, and deployment — I just open n8n and build workflows. If you're building automations for clients and you care about data privacy and cost, self-hosting n8n on Hetzner is one of the better decisions you can make early on.The biggest gotcha: n8n stores credentials encrypted with your encryption key. If you ever lose that key or change it, all your stored credentials become unreadable. Save that key somewhere safe — a password manager works fine.
Keeping It Running
Cost Breakdown
Conclusion
WEBHOOK_URL, and saving your encryption key somewhere safe.