Category: Docker

  • Complete Guide: Install n8n with Docker and HTTPS on Ubuntu 24.04

    Complete Guide: Install n8n with Docker and HTTPS on Ubuntu 24.04

    Installing n8n with Docker and HTTPS on Ubuntu 24.04 gets you a production-ready, self-hosted automation server in about 15 minutes: Docker for isolation, Postgres for persistent workflow storage, and Caddy for automatic, zero-config SSL.

    Why Use n8n with Docker on Ubuntu 24.04

    Running n8n in Docker instead of a bare-metal install keeps upgrades to a single docker compose pull && docker compose up -d, isolates n8n’s Node.js runtime from the rest of the system, and makes the whole stack reproducible if you ever need to rebuild the server. Pairing it with Postgres instead of the default SQLite avoids the file-locking issues SQLite runs into once you have more than a couple of concurrent workflow executions.

    Prerequisites Before Installing n8n

    You’ll need an Ubuntu 24.04 server with root or sudo access, a domain name pointed at the server’s IP (an A record), and ports 80 and 443 open in your firewall/security group — Caddy needs both to complete the automatic HTTPS certificate challenge.

    Install Docker on Ubuntu 24.04

    sudo apt update
    sudo apt install docker.io docker-compose-plugin -y
    sudo systemctl enable docker
    sudo systemctl start docker
    docker --version

    Create Docker Compose for n8n and Postgres

    Create a docker-compose.yml defining both services. n8n talks to Postgres over the internal Docker network, so only n8n’s port needs to be exposed to the host.

    version: "3.8"
    
    services:
      postgres:
        image: postgres:16
        restart: always
        environment:
          POSTGRES_USER: n8n
          POSTGRES_PASSWORD: strongpassword
          POSTGRES_DB: n8n
        volumes:
          - ./data/postgres:/var/lib/postgresql/data
    
      n8n:
        image: n8nio/n8n
        restart: always
        ports:
          - "5678:5678"
        environment:
          DB_TYPE: postgresdb
          DB_POSTGRESDB_HOST: postgres
          DB_POSTGRESDB_DATABASE: n8n
          DB_POSTGRESDB_USER: n8n
          DB_POSTGRESDB_PASSWORD: strongpassword
        depends_on:
          - postgres

    Replace strongpassword with a real generated password (e.g. openssl rand -base64 24) before you start the stack — don’t leave the placeholder in a production file.

    Configure HTTPS with Caddy

    Caddy issues and renews Let’s Encrypt certificates automatically the first time it sees a request for the domain, with no manual certbot step. Point your domain’s A record at the server first, then add a Caddyfile:

    automation.yourdomain.com {
        reverse_proxy localhost:5678
    }

    If n8n and Caddy are both containers on the same Docker network, use the n8n service name instead of localhost: reverse_proxy n8n:5678.

    Start n8n with Docker Compose

    docker compose up -d
    docker compose logs -f

    Verifying the Installation

    Run docker compose ps and confirm both n8n and postgres show a status of Up (or healthy if you’ve added healthchecks). Then open https://automation.yourdomain.com in a browser — you should land on n8n’s setup screen with a valid padlock/certificate, not a security warning. If the page doesn’t load, check the Troubleshooting section below before assuming the install failed; the two services almost always start correctly, and the reverse proxy or DNS record is the more common culprit.

    Quick Reference Commands

    # Check container status
    docker compose ps
    
    # Follow n8n logs only
    docker compose logs -f n8n
    
    # Restart just n8n after a config change
    docker compose restart n8n
    
    # Pull the latest n8n image and recreate
    docker compose pull n8n
    docker compose up -d n8n
    
    # Export all workflows before an update
    docker compose exec n8n n8n export:workflow --all --output=/home/node/backup.json

    Troubleshooting

    n8n container restarts in a loop: run docker compose logs n8n — this is almost always a database connection failure. Confirm DB_POSTGRESDB_PASSWORD in the n8n service matches POSTGRES_PASSWORD in the postgres service exactly, and that depends_on is giving Postgres enough time to accept connections before n8n’s first attempt.

    Browser shows a certificate warning or “connection refused”: this is a Caddy/DNS problem, not an n8n problem. Check docker compose logs caddy (or Caddy’s own log if it’s running outside Docker) — a failed ACME challenge usually means the domain’s A record isn’t pointing at this server yet, or port 80/443 is blocked by a firewall or cloud security group.

    Webhooks aren’t firing from external services: n8n needs to know its own public URL to generate correct webhook URLs. Set the WEBHOOK_URL environment variable (e.g. WEBHOOK_URL=https://automation.yourdomain.com/) on the n8n service and restart it.

    Security, Backups, and Maintenance

    Back up the ./data/postgres volume regularly — that’s where every workflow, credential, and execution history lives. A simple approach is docker compose exec postgres pg_dump -U n8n n8n > backup.sql on a cron schedule, or exporting workflows with the CLI command shown above before any update. Test upgrades on a non-production instance first: pull the new n8n image, check the release notes for breaking changes, then update production during a low-traffic window. Because Caddy terminates HTTPS in front of n8n, your login credentials and webhook payloads are encrypted in transit by default — there’s no separate TLS configuration to maintain on the n8n side.

    FAQ

    Do I need Postgres, or can I use the default SQLite?
    SQLite works for light personal use, but it locks the whole database file during writes, which causes errors once you have multiple workflows executing concurrently. Postgres is the recommended default for anything beyond a single-user test instance.

    Can I run this on a subdomain I already use for something else?
    Yes — Caddy can reverse-proxy multiple domains/subdomains from one Caddyfile, each with its own block. n8n itself doesn’t need a dedicated server.

    What Ubuntu versions besides 24.04 does this work on?
    The same Docker Compose file works on any Ubuntu LTS release with Docker installed (20.04, 22.04, 24.04) — 24.04 is used here because it’s the current LTS at time of writing.

    Final Thoughts

    Docker Compose, Postgres, and Caddy together give you a self-hosted n8n instance that’s easy to back up, easy to upgrade, and secured with HTTPS by default — a solid foundation whether you’re automating a handful of personal workflows or running production integrations. Once it’s running, the natural next steps are exploring pre-built n8n templates to speed up building your first workflows, or reading how n8n compares to hosted alternatives if you’re still deciding on a platform.