You've hit the wall every operator hits with n8n Cloud: your automations are working, so now every extra execution has a price tag attached. Self-hosting n8n fixes that. You run the same tool on a $5 to $12 a month VPS using Docker, and you stop paying per task for good.
To self host n8n: rent a small Linux VPS (Hetzner, DigitalOcean, or Vultr), install Docker and Docker Compose, and run n8n as a container behind Caddy for free automatic HTTPS. Point a domain at the server, set your encryption key and webhook URL as environment variables, and you're running a production instance in under 30 minutes.
Here's what actually decides whether this holds up long term: right-sizing the VPS, getting HTTPS correct on day one, and treating the encryption key and data volume like the two things you cannot afford to lose. Undersize the box and webhook-heavy workflows queue up under load. Skip HTTPS and half the OAuth-based integrations won't let you connect. Lose the encryption key without a separate backup and every stored credential goes dead at once. None of this is hard, it's just easy to skip when a tutorial rushes you through docker compose up and calls it done. This also assumes you already know n8n's canvas: if not, get comfortable there first with our n8n for marketing beginners guide, then come back to deploy it for real.
Four things: a VPS, a domain or subdomain, SSH access, and about half an hour where nothing interrupts you.
n8n.yourdomain.com is the standard pattern, a spare subdomain on a domain you already own works fine.Any provider that hands you a plain Ubuntu box works: Hetzner, DigitalOcean, Vultr, and Contabo are the four operators reach for most, the specs matter more than the brand. For a solo operator running a normal mix of automations, a few dozen workflows with occasional bursts, look for:
Expect to land around $4 to $12 a month for a box that comfortably handles a solo operator's workload, that's your entire infrastructure bill no matter how many times your workflows run.
Five steps once you can SSH into the box: update it, install Docker, write two small config files, and start the container.
1. Update the server and install Docker.
sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
Log out and back in so the group change takes effect.
2. Create a project folder and an environment file.
mkdir ~/n8n && cd ~/n8n
nano .env
Inside .env, set at minimum:
N8N_HOST=n8n.yourdomain.com
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.yourdomain.com/
GENERIC_TIMEZONE=America/New_York
N8N_ENCRYPTION_KEY=replace-with-a-long-random-string-you-save-elsewhere
3. Write the docker-compose.yml. Bind n8n to localhost only, you'll expose it through a reverse proxy next:
services:
n8n:
image: n8nio/n8n
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
env_file: .env
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:
4. Start it.
docker compose up -d
5. Confirm it's alive.
docker compose ps
curl http://localhost:5678
A response instead of a connection error means n8n is running, just not reachable from outside the server yet. That's next.
Point DNS at your server, then let a reverse proxy issue and renew the certificate for you. Caddy is the fastest path: no certbot cron jobs, no manual renewal.
First, the DNS. In your registrar, add an A record pointing n8n.yourdomain.com at your VPS's IP address, give it a few minutes to propagate.
Then add Caddy to your stack. Create a Caddyfile next to your docker-compose.yml:
n8n.yourdomain.com {
reverse_proxy n8n:5678
}
And add the Caddy service to docker-compose.yml:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
depends_on:
- n8n
Add caddy_data: under volumes:, then run docker compose up -d again. Lock down the firewall too: a one-click panel from most providers, or ufw allow 22,80,443/tcp && ufw enable.
Within a minute or two, https://n8n.yourdomain.com loads with a valid certificate, no browser warnings. Open it, land on n8n's first-run setup screen, and create your owner account there, that's your login from now on. Don't skip this step: several of n8n's most useful integrations, Google Workspace, Slack, HubSpot, anything built on OAuth, require a real HTTPS redirect URL before they'll let you register the connection.
Not on day one. n8n ships with SQLite by default, and for a solo operator running dozens of workflows, it holds up fine. Switch once you hit any of these:
Moving to Postgres later is a config change, not a rebuild: add a postgres service to your compose file and point n8n at it with DB_TYPE=postgresdb plus the connection variables. There's no cost to starting on SQLite and upgrading only once your usage demands it.
Back up two things on a schedule: the data volume and the encryption key. The key matters more.
For backups, run a nightly cron job that archives the volume and ships it off the VPS. Create a ~/backups folder once, then run:
docker run --rm -v n8n_n8n_data:/data -v ~/backups:/backup alpine \
tar czf /backup/n8n-$(date +%F).tar.gz /data
Push it somewhere off the VPS, object storage or another machine. If the server disappears tomorrow, that archive plus your saved encryption key rebuilds everything.
For updates, pull the new image and recreate the container:
docker compose pull
docker compose up -d
Two habits keep this safe: pin your image to a version tag instead of latest in production, and read release notes before a major version jump, breaking changes land occasionally and you want to know before, not after.
The mechanism decides this, not a specific dollar figure: Cloud plans meter you by execution volume, so your bill climbs as your automations fire more often. A self-hosted VPS charges a flat monthly fee whether it processes 50 executions or 50,000, the ceiling is how much load the hardware can handle, not how many times something ran. Same logic holds for Zapier for marketing automation or Make.com for marketing automation, both meter you the same way n8n Cloud does.
That flips the incentive: a workflow firing every time a lead fills out a form is a cost center that grows with your marketing, on a metered plan. Self-hosted, it's free once the server's paid for, in exchange you own uptime, patches, and backups. That trade favors self-hosting past a trivial volume, especially for operators already running other pieces of their stack through no-code marketing workflows. There's a bigger payoff too: n8n becomes the layer connecting your AI agents to the tools they act on, whether you're learning what MCPs are and how to connect them or already know how to run AI agents on a schedule.
The docker-compose.yml and Caddyfile above are a solid starting point, but your domain, database, and workload aren't identical to the example. Feed your specifics to an AI model and have it generate the exact files.
You are a DevOps engineer who deploys self-hosted n8n instances for a living. Generate a complete docker-compose.yml, Caddyfile, and .env template for a self-hosted n8n instance with these specs: - Domain: [n8n.yourdomain.com] - VPS OS: [Ubuntu 24.04] - Database: [SQLite for now / Postgres for production] - Timezone: [America/New_York] - Expected workflow load: [e.g. "20 workflows, mostly webhook-triggered, low volume" or "200+ executions a day, heavy on schedules"] - Need queue mode (Redis + separate worker containers): [yes/no] Requirements: 1. Pin the n8n image to a specific version tag, not "latest" 2. Caddy reverse proxy with automatic HTTPS via Let's Encrypt 3. A named volume for persistent n8n data 4. All secrets (encryption key, DB password) in a separate .env file, never hardcoded into the compose file 5. Inline comments explaining each environment variable and which ones I must change before deploying Output the docker-compose.yml, the Caddyfile, and the .env template as three separate, clearly labeled code blocks.
Swap the bracketed values for your real domain, OS, and load, then read every line before you run it, especially the encryption key handling and which ports get exposed.
Self-hosting removes the per-execution cost ceiling, and in exchange it hands you every job a managed platform used to quietly handle. If the VPS goes down at 2am from a bad kernel update or a full disk, nobody fixes that but you: no support ticket, no status page, no on-call team.
The Community Edition isn't the full product either. Enterprise features like SSO, granular permissions, and environment promotion across dev, staging, and production sit behind n8n's paid tiers even when you self-host the core. A solo operator won't miss most of this, a growing team will.
An exposed, unsecured n8n instance gets found within hours of going live, port scanners hit the entire internet constantly. The owner-account setup n8n forces on first login is your baseline protection: don't skip it, and don't reuse a password from anywhere else.
And a $5 box is genuinely underpowered for bursty workloads, dozens of webhooks firing in the same second, or one trigger cascading into fifty downstream executions. That's not a self-hosting problem, it's a sizing problem: a bigger VPS or queue mode fixes it, not abandoning the approach.
The core software is free to self-host under n8n's Sustainable Use License, including commercial use. Your real cost is the VPS, $4 to $12 a month, plus your own setup and maintenance time.
No. Building workflows inside n8n is visual, drag-and-drop node wiring, identical to n8n Cloud. Setting up the server is the only part touching a command line, a fixed set of commands you copy-paste once.
Technically, but it defeats most of the point. Webhooks and scheduled triggers need a server that's online and reachable 24/7, and a laptop that sleeps, reboots, or sits behind home NAT breaks that the first time it happens.
Export each workflow as JSON from the Cloud editor and import it the same way into your self-hosted instance. Credentials don't travel with the export, so budget time to re-enter API keys and reconnect OAuth logins.
Every stored credential becomes unreadable, and you'll need to re-enter every API key and reconnect every OAuth integration across every workflow. Save the key outside the server the same day you set it, thirty seconds now beats a very bad afternoon later.
Getting n8n running is the easy part: the 30 minutes this walkthrough promised. Running it like real infrastructure, queue mode once volume demands it, error workflows that actually alert you, credential rotation, tested backups, is what most solo operators figure out alone, usually during their first outage. If you'd rather build that alongside operators doing this daily instead of debugging it solo, come work through it inside Asset Academy on Skool.
Inside the Asset Academy community we build the copy, funnels, and offers together, with the prompts and the feedback. $96/mo, or save with annual.
Join the community →The community where we build the copy, funnels, and offers together, with the prompts and live feedback.
Join the Community →