Blogguides

n8n self-hosted setup guide: run your own automation server in 20 minutes

Affiliate disclosure: This site earns a commission when you sign up for tools through links on this page, at no extra cost to you. I only recommend tools I've researched and would use myself.

The cloud version of n8n costs ~$28/month for 2,500 executions. The self-hosted version costs $0 in software fees and about $5/month in server costs — with unlimited executions.

That math isn't close. If you run more than a few workflows, self-hosting pays for itself inside the first month.

This guide gets you from zero to a fully running, SSL-secured n8n instance in about 20 minutes. No prior server experience required, but you'll need to be comfortable running commands in a terminal.

What you'll end up with

  • n8n running at https://your-domain.com
  • PostgreSQL as the database (the production-ready choice)
  • Nginx as a reverse proxy handling HTTPS
  • Free SSL certificate from Let's Encrypt
  • Unlimited executions, unlimited workflows, unlimited users
  • A registered Community Edition license (unlocks Folders, Debug mode, and custom execution data — for free)

What you'll need before starting

  • A VPS with at least 1 vCPU and 1GB RAM (2 vCPU / 4GB RAM recommended for production)
  • A domain or subdomain pointed at your server's IP address
  • SSH access to the server
  • About 20 minutes

VPS options that work: DigitalOcean Droplet (~$6/mo for 1GB RAM), Hetzner CX22 (~$4.60/mo for 2 vCPU / 4GB RAM — best value), Oracle Cloud Always Free ARM (free, 4 vCPU / 24GB RAM — best deal if you can get it set up).

For this guide I'll assume a fresh Ubuntu 22.04 or 24.04 server.


Step 1 — Point your domain at the server

Before anything else, create a DNS A record pointing your domain (or subdomain like n8n.yourdomain.com) to your server's IP address.

DNS propagation takes 5–60 minutes. Start here so it's done by the time you need it.


Step 2 — Install Docker

SSH into your server and run the official Docker install script:

curl -fsSL https://get.docker.com | sh

That's it. Docker and Docker Compose ship together since Docker Engine v20.10 — you don't need to install them separately.

Verify it worked:

docker --version
docker compose version

Both should return version numbers. If not, restart your SSH session and try again.


Step 3 — Create the n8n directory and Docker Compose file

mkdir -p ~/n8n && cd ~/n8n

Create a docker-compose.yml file:

nano docker-compose.yml

Paste in this configuration (replace the values in < > with your own):

version: "3.8"

services:
  postgres:
    image: postgres:16
    restart: always
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: <your-strong-db-password>
      POSTGRES_DB: n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data

  n8n:
    image: n8nio/n8n:latest
    restart: always
    ports:
      - "5678:5678"
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=<your-strong-db-password>
      - N8N_HOST=<your-domain.com>
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://<your-domain.com>/
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=<your-username>
      - N8N_BASIC_AUTH_PASSWORD=<your-strong-password>
      - GENERIC_TIMEZONE=America/New_York
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - postgres

volumes:
  postgres_data:
  n8n_data:

Three things to replace before saving:

  1. Both instances of <your-strong-db-password> — use the same password in both places
  2. All three instances of <your-domain.com> — use your actual domain
  3. <your-username> and <your-strong-password> — this is your n8n login

For the timezone, change America/New_York to your own. Full list: TZ database names.

Save and close: Ctrl+X, then Y, then Enter.


Step 4 — Start n8n

docker compose up -d

Docker will pull the images and start both containers. First run takes 1–2 minutes. After that:

docker compose ps

You should see both postgres and n8n with a status of Up.

At this point, n8n is running on port 5678. You can technically access it at http://your-server-ip:5678 — but don't use it like that. Set up Nginx and SSL first.


Step 5 — Install Nginx and Certbot

sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx

Create an Nginx configuration file for n8n:

sudo nano /etc/nginx/sites-available/n8n

Paste this (replace your-domain.com with your actual domain):

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        chunked_transfer_encoding on;
        proxy_buffering off;
        proxy_read_timeout 3600s;
    }
}

Enable the site and test the config:

sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

You should see syntax is ok and test is successful.


Step 6 — Get your free SSL certificate

sudo certbot --nginx -d your-domain.com

Certbot will ask for your email (for renewal alerts) and prompt you to agree to the terms. Say yes. It automatically edits your Nginx config to handle HTTPS.

Verify renewal works:

sudo certbot renew --dry-run

No errors = you're good. The cert auto-renews every 90 days.

Your n8n instance is now live at https://your-domain.com. Open it in a browser and log in with the username and password you set in Step 3.


Step 7 — Register for your free Community Edition license

The free Community Edition already includes unlimited executions, unlimited workflows, and all 500+ integrations. But registering unlocks three extra features for free:

  • Folders — organize workflows into folders (you'll want this once you have 20+)
  • Debug in editor — copy and pin execution data for faster troubleshooting
  • Custom execution data — tag and annotate execution runs

To register: inside n8n, go to Settings → Usage and Plan → Activate community edition. Enter your email. You'll receive a license key. Paste it in. Done.

No credit card. No subscription. Just three useful features, free.


Troubleshooting — the three things that actually go wrong

n8n won't start / containers keep restarting

Check the logs:

docker compose logs n8n --tail=50

The most common cause: the WEBHOOK_URL includes a trailing slash and the domain in N8N_HOST doesn't match the domain you actually registered. Make sure they're identical.

SSL certificate fails ("Connection refused")

Certbot needs to reach your server over port 80 to verify domain ownership. If it fails, check that your VPS firewall allows ports 80 and 443:

sudo ufw allow 80
sudo ufw allow 443
sudo ufw reload

Also double-check your DNS A record is pointing to the right IP.

Webhook triggers don't fire

n8n needs to know its public URL to build correct webhook URLs. If WEBHOOK_URL is wrong — wrong domain, HTTP instead of HTTPS, missing trailing slash — webhooks will be built with the wrong URL and external services won't be able to reach them.

Stop the containers, fix the value in docker-compose.yml, then:

docker compose down && docker compose up -d

Keeping n8n updated

When a new n8n version drops:

cd ~/n8n
docker compose pull
docker compose up -d

That pulls the latest image and restarts the containers. Your workflows and credentials are stored in the PostgreSQL database (persisted in the postgres_data volume) — they're safe across updates.


The actual cost breakdown

| Item | Cost | |---|---| | n8n software | $0 (open source, Community Edition) | | Hetzner CX22 VPS (2 vCPU / 4GB RAM) | ~$4.60/month | | Domain (if you don't have one) | $10–15/year | | SSL certificate (Let's Encrypt) | $0 | | Total | ~$5/month |

Compare that to n8n Cloud Starter at ~$28/month with a 2,500 execution cap. Self-hosted at $5/month has no cap at all.

The catch — and there's always one — is that you own the maintenance. Updates, backups, server uptime. It's not complicated, but it is real. If you want to run automation workflows without thinking about servers, the cloud version is still the right call. If you're running more than a handful of workflows regularly, the math points here.

Try n8n Cloud free for 14 days if you want to test workflows before committing to the self-hosted path. The setup is identical — your workflows transfer.


What to build next

Once n8n is running, the highest-ROI workflows to set up first:

  • AI email digest — fetch RSS feeds, summarize with Claude or GPT, email yourself daily
  • Content publishing trigger — watch a folder for new MDX files, post to social on publish
  • Lead enrichment — pull new form submissions, enrich with Hunter.io, log to a sheet

The n8n documentation has workflow templates for all three. Start with one, get it running, then expand.

Get started with n8n

This post may contain affiliate links. I earn a commission if you purchase through a link, at no extra cost to you. I only recommend tools I've honestly assessed.

← Back to all posts