n8n Self Hosted: Full Docker Installation Guide 2026

n8n Self Hosted: The Complete Docker Setup and Hardening Guide

Disclosure: This post contains one or more links to providers we have a real, registered affiliate/referral relationship with. We may earn a commission at no extra cost to you if you sign up through them.

If you’re tired of paying monthly fees for Zapier or Make, running n8n self hosted on your own VPS is one of the highest-leverage moves you can make as a developer or sysadmin. You get unlimited workflow executions, full data ownership, and no per-task billing — for the cost of a $6/month server.

This guide covers everything you need to run n8n self hosted in production: Docker Compose setup, reverse proxy configuration, database choice, backups, and scaling with queue mode.

Why Self-Host n8n

n8n is an open-source workflow automation tool — think Zapier, but with a visual node editor and the ability to write custom JavaScript inside any node. The hosted cloud version is convenient, but it caps executions and charges per active workflow. Self-hosting removes both limits.

When you run n8n self hosted, you also get:

  • Full control over data retention and where your credentials are stored
  • No vendor lock-in — export/import workflows as JSON anytime
  • The ability to run community and custom nodes that aren’t approved for n8n Cloud
  • Direct network access to internal services (databases, internal APIs) without exposing them publicly
  • The tradeoff is that you own the ops burden: updates, backups, uptime, and security. This guide addresses all four.

    n8n vs Zapier and Make

    If you’re evaluating whether to self-host at all, the deciding factor is usually volume and complexity. Zapier and Make are fine for a handful of simple, low-frequency automations. Once you’re running dozens of workflows with branching logic, webhooks, and custom code, the per-task pricing on those platforms gets expensive fast, and n8n self hosted becomes the more economical option, especially at scale.

    Prerequisites

    Before you start, you’ll need:

  • A VPS with at least 1 vCPU and 2GB RAM (n8n is fairly lightweight, but PostgreSQL and Redis add overhead if you use queue mode)
  • Docker and Docker Compose installed
  • A domain name you control, with DNS pointed at your server’s IP
  • Basic familiarity with the command line
  • If you don’t already have a VPS, DigitalOcean and Hetzner both offer affordable droplets/instances that are more than capable of running n8n comfortably — a $12/month droplet handles most single-user workloads without issue.

    Installing n8n with Docker

    The fastest, most maintainable way to run n8n self hosted is with Docker Compose. This keeps n8n, its database, and any supporting services isolated and easy to upgrade.

    First, create a project directory and the required subfolders:

    mkdir -p ~/n8n-stack/local-files
    cd ~/n8n-stack

    Docker Compose Setup

    Create a docker-compose.yml file with the following contents:

    version: '3.8'
    
    services:
      postgres:
        image: postgres:16
        restart: unless-stopped
        environment:
          - POSTGRES_USER=n8n
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
          - POSTGRES_DB=n8n
        volumes:
          - postgres_data:/var/lib/postgresql/data
        healthcheck:
          test: ['CMD-SHELL', 'pg_isready -U n8n']
          interval: 5s
          timeout: 5s
          retries: 10
    
      n8n:
        image: docker.n8n.io/n8nio/n8n:latest
        restart: unless-stopped
        ports:
          - '127.0.0.1:5678:5678'
        environment:
          - N8N_HOST=${DOMAIN_NAME}
          - N8N_PROTOCOL=https
          - N8N_PORT=5678
          - WEBHOOK_URL=https://${DOMAIN_NAME}/
          - DB_TYPE=postgresdb
          - DB_POSTGRESDB_HOST=postgres
          - DB_POSTGRESDB_DATABASE=n8n
          - DB_POSTGRESDB_USER=n8n
          - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
          - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
          - GENERIC_TIMEZONE=UTC
        volumes:
          - n8n_data:/home/node/.n8n
          - ./local-files:/files
        depends_on:
          postgres:
            condition: service_healthy
    
    volumes:
      postgres_data:
      n8n_data:

    Next, create a .env file to hold your secrets — never commit this to version control:

    cat > .env << 'EOF'
    DOMAIN_NAME=n8n.yourdomain.com
    POSTGRES_PASSWORD=change_this_to_a_long_random_string
    N8N_ENCRYPTION_KEY=change_this_to_another_long_random_string
    EOF

    Generate strong random values instead of the placeholders:

    openssl rand -hex 32

    Run that command twice and paste the outputs into POSTGRES_PASSWORD and N8N_ENCRYPTION_KEY respectively. The encryption key is critical — it encrypts stored credentials, and if you lose it, you lose access to every saved credential in your workflows. Back it up somewhere safe outside the server.

    Now bring the stack up:

    docker compose up -d

    Check that both containers are healthy:

    docker compose ps
    docker compose logs -f n8n

    At this point n8n is running on 127.0.0.1:5678, bound only to localhost. It isn’t reachable from the internet yet — that’s intentional. We’ll expose it safely through a reverse proxy in the next section.

    Setting Up a Reverse Proxy with HTTPS

    Running n8n behind a reverse proxy with TLS is non-negotiable for anything beyond local testing, since n8n handles webhooks and stored credentials. Nginx with Let’s Encrypt is the simplest combination.

    Install Nginx and Certbot on the host:

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

    Create a server block at /etc/nginx/sites-available/n8n:

    server {
        listen 80;
        server_name n8n.yourdomain.com;
    
        location / {
            proxy_pass http://127.0.0.1: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;
        }
    }

    Enable the site and issue a certificate:

    sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
    sudo nginx -t && sudo systemctl reload nginx
    sudo certbot --nginx -d n8n.yourdomain.com

    Certbot will automatically rewrite the config for HTTPS and set up renewal. If you’d rather use Traefik with automatic Let’s Encrypt via Docker labels, our Traefik reverse proxy guide walks through that setup in detail, and it pairs well with the Compose file above.

    Database Configuration: SQLite vs PostgreSQL

    By default, n8n ships with SQLite, which is fine for quick testing but not recommended for production. SQLite struggles under concurrent writes, and a corrupted database file can silently break your entire instance with no easy recovery path. PostgreSQL, as configured in the Compose file above, handles concurrent workflow executions far more reliably and makes backups straightforward with standard tooling like pg_dump.

    If you’re already running PostgreSQL for other services, you can point n8n at that instance instead of running a dedicated container — just make sure the DB_POSTGRESDB_HOST environment variable resolves correctly from inside the n8n container’s network.

    Securing Your n8n Instance

    A self-hosted automation tool that stores API keys and OAuth tokens for every service you connect is a high-value target if compromised. Treat it accordingly.

  • Enable n8n’s built-in user management (Settings → Users) so the instance isn’t wide open to anyone with the URL
  • Restrict SSH access to key-based auth only and disable root login
  • Keep the Docker image updated regularly — docker compose pull && docker compose up -d pulls the latest patched release
  • Set N8N_BLOCK_ENV_ACCESS_IN_NODE=true to prevent workflow code nodes from reading host environment variables
  • Put the server behind a firewall that only allows ports 22, 80, and 443
  • For a full server hardening checklist beyond n8n specifically, see our guide on securing a self-hosted VPS, which covers fail2ban, unattended upgrades, and SSH hardening in more depth.

    If uptime matters for your automations — for example, workflows that process incoming webhooks from payment providers — it’s worth pairing your instance with an external monitoring service. BetterStack offers uptime monitoring and status pages that will alert you immediately if your n8n instance or its webhook endpoint goes down, which is far better than discovering a failed workflow days later.

    Backups

    Backups need to cover two things: the PostgreSQL database (your workflow definitions and execution history) and the n8n_data volume (which holds the encryption key and local file storage).

    A simple daily backup script:

    #!/bin/bash
    set -euo pipefail
    
    BACKUP_DIR=/root/n8n-backups
    TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    mkdir -p "$BACKUP_DIR"
    
    docker compose exec -T postgres pg_dump -U n8n n8n | gzip > "$BACKUP_DIR/n8n-db-$TIMESTAMP.sql.gz"
    docker run --rm -v n8n-stack_n8n_data:/data -v "$BACKUP_DIR":/backup alpine 
      tar czf "/backup/n8n-data-$TIMESTAMP.tar.gz" -C /data .
    
    find "$BACKUP_DIR" -type f -mtime +14 -delete

    Schedule it with cron:

    crontab -e
    # Add the following line:
    0 3 * * * /root/n8n-backup.sh >> /var/log/n8n-backup.log 2>&1

    Copy the backups off the server itself — to object storage or another machine — since a backup that lives only on the server it’s protecting isn’t a real backup.

    Scaling n8n with Queue Mode

    If you’re running high-volume or long-running workflows, the default setup can become a bottleneck because a single n8n process handles both the UI and execution. Queue mode splits this: a main process handles the editor and webhook triggers, while separate worker processes pull jobs from a Redis-backed queue and execute them.

    To enable it, add a Redis service to your Compose file and set these additional environment variables on the n8n service:

      redis:
        image: redis:7-alpine
        restart: unless-stopped

    EXECUTIONS_MODE=queue
    QUEUE_BULL_REDIS_HOST=redis

    Then run a separate worker container using the same image with the command n8n worker. This lets you scale workers horizontally as workflow volume grows, without touching the main instance.

    Monitoring and Observability

    Once n8n is handling anything business-critical, blind spots become expensive. At minimum, track:

  • Container health via docker compose ps and restart policies
  • Disk usage on the volumes, since execution history can grow unbounded if you don’t configure EXECUTIONS_DATA_PRUNE
  • HTTP response codes on the reverse proxy for failed webhook deliveries
  • Our Docker Compose monitoring guide shows how to wire up Prometheus and Grafana against a Compose stack like this one if you want dashboards rather than just log tailing.

    Recommended: Want to explore DigitalOcean yourself? DigitalOcean is a direct vendor link (not an affiliate/tracked link).

    FAQ

    Is n8n free to self-host?
    Yes. The core n8n software is fair-code licensed and free to self-host with no execution limits. You only pay for the server it runs on and optional enterprise features if you need SSO or advanced permissions.

    How much does it cost to run n8n self hosted?
    A small VPS with 1-2 vCPUs and 2GB of RAM, typically $6-12/month from providers like DigitalOcean or Hetzner, is enough for most individual or small-team workloads.

    Do I need PostgreSQL, or can I stick with SQLite?
    SQLite works for testing, but PostgreSQL is strongly recommended for production because it handles concurrent executions more reliably and supports standard backup tooling.

    Can I run n8n without Docker?
    Yes, n8n can be installed via npm directly on the host, but Docker is recommended because it isolates dependencies, simplifies upgrades, and matches the environment n8n is tested against.

    How do I update a self-hosted n8n instance safely?
    Back up your database and volumes first, then run docker compose pull followed by docker compose up -d. Check the n8n release notes for breaking changes before upgrading across major versions.

    Is it safe to expose n8n’s webhook URLs publicly?
    Yes, that’s expected usage, but only expose them behind HTTPS via a reverse proxy, and enable user authentication on the editor UI so the workflow builder itself isn’t publicly accessible.

    Final Thoughts

    Running n8n self hosted takes maybe 30 minutes of setup time and gives you a private, unlimited automation platform that competes with tools costing hundreds of dollars a month at scale. Start with the Docker Compose setup above, put it behind HTTPS, automate your backups, and you’ll have a production-grade instance before the end of the afternoon.

    Comments

    Leave a Reply

    Your email address will not be published. Required fields are marked *