Cover: n8n Docker Setup: The Complete Self-Hosting Guide
October 9, 2026·7 min read·1,588 words·

n8n Docker Setup: The Complete Self-Hosting Guide

How to run n8n on Docker with a real domain, HTTPS webhooks, Postgres and backups that actually restore when you need them. Analysis from HostList.io.

Running n8n on Docker means pulling the official n8n image, mapping a persistent volume for the /home/node/.n8n directory, and putting the container behind a reverse proxy that terminates TLS on a real domain. n8n simply won't behave over plain HTTP or on localhost once webhooks enter the picture. That's the whole job in one sentence. The rest of this guide is the order you actually do it in, and the three places people get it wrong.

Why Docker instead of installing n8n directly on the server?

You can install n8n with npm on a bare VPS and it will run. For about a week. Then a Node version mismatch, a missing native dependency, or an OS package update breaks something, and you're debugging tooling instead of workflows. n8n's own documentation is blunt about this: Docker sidesteps operating system and tooling incompatibilities entirely, and managing the database connection and environment variables is far simpler when everything sits in one file rather than scattered across shell profiles and system services. I've had clients try the bare-metal route to "keep things simple" and end up with a harder problem than the one they were avoiding. Docker is the boring, correct choice here.

Which server should you actually run n8n on?

n8n is not resource-hungry at rest, but workflow executions spike CPU and memory depending on what you're automating. A small VPS with 2 vCPUs and 4GB RAM handles a moderate workflow load comfortably for most solo and small-team setups. Running heavy data transforms, AI API chaining, or high webhook volume? Size up before you need to. Resizing under load is more painful than provisioning correctly the first time. Check our best VPS hosting picks if you're starting from scratch, and if you're already set on containers specifically, our best Docker hosting comparison and the n8n hosting rankings will save you a few wasted evenings comparing providers that all look identical on the surface but aren't.

One thing worth flagging: if you're planning to run n8n alongside other automation or agent tooling, like OpenClaw, on the same box, check host requirements for both before you provision. Our OpenClaw hosting guide covers resource profiles that differ meaningfully from n8n's.

How do you point a domain at your n8n server?

Before you touch Docker, get DNS sorted. n8n webhooks are the entire point of self-hosting the tool, and webhooks from third-party services (Stripe, Slack, Typeform, whatever you're wiring up) need to hit a public hostname, not an IP address and definitely not localhost. Create an A record pointing your chosen subdomain, something like n8n.YOUR_DOMAIN.com, at your server's public IP. Give it time to propagate and verify it's actually resolving with our DNS checker before you move on. Skip this step and try to fix DNS after the container's already running, and that's where most of the wasted afternoons come from.

Why does n8n need HTTPS before you've even logged in?

This is the part almost every setup guide treats as optional, and it isn't. n8n's webhook URLs are generated from the environment variables you set, and if those variables don't match a hostname served over HTTPS, incoming webhooks will silently fail or resolve to the wrong place. Not "throw an error you can debug." Silently fail. I've had a client spend two days convinced their Stripe integration was broken when the actual problem was that WEBHOOK_URL was still pointing at an HTTP address with no certificate behind it. DNS and TLS aren't nice-to-haves you add later. They're part of the install.

How do you run n8n behind a reverse proxy with TLS?

The standard pattern is Nginx or Caddy in front of the n8n container, handling certificate issuance and renewal, then proxying traffic to n8n's internal port. Caddy is the lower-friction option because it handles Let's Encrypt certificate issuance and renewal automatically with almost no configuration. Nginx gives you more control if you're already comfortable with it. Either way the shape of the setup is the same:

  • Reverse proxy listens on 443 for your domain (n8n.YOUR_DOMAIN.com)
  • Proxy forwards to the n8n container's internal port, typically localhost:5678
  • Certificate is issued and renewed automatically against the domain you pointed in DNS

Once it's live, don't just eyeball the padlock icon and assume it's fine. Run the domain through our SSL checker to confirm the chain is valid and nothing's expiring in the next few weeks. A lapsed certificate on a webhook endpoint means every integration relying on it goes dark without warning.

What does the docker-compose file actually need to contain?

Rather than paste a block of YAML that will be out of date by the time n8n ships its next release, here's the shape of what a working docker-compose.yml needs, using placeholders you fill in:

services:
  n8n:
    image: n8nio/n8n:LATEST_TAG
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      - N8N_HOST=n8n.YOUR_DOMAIN.com
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.YOUR_DOMAIN.com/
      - N8N_ENCRYPTION_KEY=YOUR_LONG_RANDOM_KEY
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=YOUR_POSTGRES_HOST
      - DB_POSTGRESDB_DATABASE=YOUR_DB_NAME
      - DB_POSTGRESDB_USER=YOUR_DB_USER
      - DB_POSTGRESDB_PASSWORD=YOUR_DB_PASSWORD
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

The exact environment variable names and defaults change between releases, so treat this as a shape, not a copy-paste block. Check n8n's Docker installation documentation for the current syntax before you deploy. It's the authoritative source and it's kept current, which a three-year-old blog post (including eventually this one) will not be.

Should you use SQLite or Postgres?

n8n ships with SQLite by default, which is fine for kicking the tyres and genuinely not fine for anything you intend to rely on. SQLite under concurrent writes on a busy workflow queue is where things start locking up in ways that are hard to diagnose. Attach a proper Postgres instance from the start, either a container in the same compose file or a managed database service if your VPS provider offers one. It's a small amount of extra setup now against a painful migration later, once you've got months of workflow history you don't want to lose. If you're scaling further, n8n also supports a queue mode setup for distributing execution load across workers, though most self-hosters won't need that on day one.

How do you stop an upgrade from wiping your workflows?

This is the mistake I see most often, and it's entirely avoidable. If your n8n data directory (/home/node/.n8n) isn't mapped to a named volume or a bind mount on the host, the moment you run docker pull and recreate the container for an upgrade, you lose your encryption key, your credentials, and every workflow you've built. The container is disposable by design. Your data has to live outside it. The compose example above maps a named volume for exactly this reason, and it's non-negotiable, not a nice-to-have for tidiness.

What actually needs backing up, and how often?

Two things matter here: the Postgres database, because that's where your workflows, execution history and credentials live, and the N8N_ENCRYPTION_KEY value, because without it your stored credentials are unreadable garbage even if the database itself is intact. Back up the database on a regular schedule using pg_dump or your provider's managed backup tooling, and store the encryption key somewhere separate from the server itself. A password manager or secrets vault, not a text file sitting next to the docker-compose.yml it's protecting.

Here's the part people skip until it's too late: a backup you have never restored is not a backup, it's a hope. Spin up a throwaway environment periodically and actually restore from your latest backup to confirm it works. I've seen more than one client discover their "backups" had been silently failing for weeks, only when they needed them for real. For a broader look at how container setups hold up under production load, our piece on where Docker hosting providers get containers wrong is worth a read, and if you're still choosing where to host the VPS underneath all this, see our VPS hosting benchmarks.

Frequently asked questions

Can I run n8n on Docker without a domain name?

You can run it for local testing, but webhooks, the reason most people self-host n8n in the first place, require a public HTTPS hostname to function. Without one you're limited to manually triggered workflows only.

Do I need Docker Compose or can I use a single docker run command?

A single docker run command works for a quick test, but once you add Postgres, a reverse proxy container, and named volumes, Compose becomes the far more manageable way to define and restart the whole stack together, rather than juggling separate commands.

How much VPS resource does n8n actually need?

It depends entirely on workflow complexity and execution frequency, not on the tool itself being heavy. Start modest, monitor actual CPU and memory usage under real workflow load, and resize before you hit a ceiling rather than after.

What happens if I lose my n8n encryption key?

Every credential stored in your workflows becomes unreadable, and there's no recovery path for it. This is precisely why the key needs to be backed up separately from the server, not just left inside the environment file with everything else.

Should you self-host n8n on Docker?

If you're comfortable owning DNS, TLS renewal and database backups, self-hosting n8n on Docker gives you full control and no per-execution pricing ceiling. If any of those three feel like a chore rather than a one-time setup, a managed n8n host will save you more time than it costs. Either way, get the domain, the certificate and the persistent volume right before you build a single workflow. Retrofitting them after the fact is where most self-hosted setups quietly go wrong.

HostList on LinkedIn
More independent hosting data

Follow HostList for new rankings, original research, and changes across the hosting industry.

Gautam Khorana
Gautam Khorana
Founder, HostList.io

Over 10,000 websites launched. Thousands of sites under management. Built HostList because the world deserves honest hosting advice.

LinkedIn →

RELATED ARTICLES

.host domains from RadixSponsor.host: a domain that says what you doPremium .host names for hosting companies and infrastructure brands, from the Radix registry.See premium .host
RadixSponsorPremium names that work like prime real estate400,000+ short, memorable premium domains across .tech, .store, .online, .site and more. 20,000+ already sold.See Radix premiums
.tech domains from RadixSponsor.tech: the address for what you buildPremium .tech names like cloud.tech and micro.tech, from Radix. Short, dictionary-word domains for tech brands.See premium .tech
.icu by ShortDotSponsor.icu: the domain that says I see youShort, memorable and cheap to start. From ShortDot, the registry behind .icu, .bond, .cfd, .sbs and .cyou.See .icu domains
ShortDotSponsorShort domains that actually get used.icu, .bond, .cfd, .sbs and .cyou: 3M+ names live across 400+ registrars. Short to type, cheap to start.See ShortDot domains
OpusDNSSponsorWelcome to the future of domainingNo platform fees, no minimum spend, personal support, seamless migration, and a developer-first REST API.Visit OpusDNS
HostPapaSponsorFast, Reliable, & Affordable Web HostingLaunch, grow and manage your website with reliable hosting, easy tools and 24/7 PapaSquad support.See HostPapa
GreenGeeksSponsorEco-Friendly WordPress Hosting DealFast WordPress performance backed by expert 24/7 support, free migration, daily backups and built-in security.See GreenGeeks

Promoted placement. Does not affect HRI, ranking order or eligibility.