> ## Documentation Index
> Fetch the complete documentation index at: https://help.freakhosting.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How to Self-Host n8n with Docker Compose

> Self-host n8n with Docker: the official Compose setup runs n8nio/n8n behind Traefik with automatic HTTPS at n8n.example.com; then create the owner account.

To self-host n8n with Docker, point `n8n.example.com` at your server, create an `.env` file and the official `compose.yaml` that runs `n8nio/n8n` behind Traefik, then run `sudo docker compose up -d`. Traefik gets a Let's Encrypt certificate automatically. Open `https://n8n.example.com` and create the owner account.

| Difficulty | Time | Works on | Needs |
| - | - | - | - |
| Intermediate | 20 minutes | Ubuntu 22.04 / 24.04, Debian 12 / 13, AlmaLinux / Rocky 9 / 10 | [Docker](https://help.freakhosting.com/portals/other/how-to-install-docker.md), a domain, ports 80 and 443 free |

## What is n8n?

n8n is a workflow automation tool. You connect apps and APIs in a visual editor, for example "when a form is submitted, add a row to a sheet and post to Discord", and n8n runs the workflow on a trigger or schedule. The self-hosted Community Edition runs on your own server.

## Before you start

* [Install Docker](https://help.freakhosting.com/portals/other/how-to-install-docker.md). The commands use `sudo`; leave it out if you are `root`.
* Create an `A` record for `n8n.example.com` pointing to your server. See [point a domain to your server](https://help.freakhosting.com/portals/other/how-to-point-a-domain-to-your-server.md).
* Ports 80 and 443 must be free, because Traefik uses them. If Nginx already runs on this server, see [use Nginx instead of Traefik](#how-to-use-nginx-instead-of-traefik).
* The n8n docs do not set a minimum for n8n alone. Their larger setup with the n8n Assistant sandbox asks for at least 4 GB RAM and 2 vCPUs.

## How to install n8n with Docker Compose

**1. Create the project folders**

```bash theme={null}
mkdir -p ~/n8n-compose/local-files && cd ~/n8n-compose
```

`local-files` is shared with n8n as `/files`, for nodes that read or write files.

**2. Create .env**

```ini theme={null}
DOMAIN_NAME=example.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/London
SSL_EMAIL=you@example.com
```

n8n is served at `https://SUBDOMAIN.DOMAIN_NAME`. `GENERIC_TIMEZONE` sets the time zone for schedule triggers. Let's Encrypt uses `SSL_EMAIL` for expiry notices.

**3. Create compose.yaml**

This is the file from the [official n8n Docker Compose guide](https://docs.n8n.io/deploy/host-n8n/install-options/use-a-cloud-provider/use-docker-compose):

```yaml theme={null}
services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - traefik_data:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - N8N_WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${GENERIC_TIMEZONE}
      - N8N_RESTRICT_FILE_ACCESS_TO=/files
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:
  traefik_data:
```

`n8nio/n8n` without a tag pulls `latest`, which n8n describes as the latest stable version. `N8N_WEBHOOK_URL` needs n8n 2.30.0 or later; older versions use `WEBHOOK_URL`.

**4. Start n8n**

```bash theme={null}
sudo docker compose up -d
```

**5. Create the owner account**

Open `https://n8n.example.com`. n8n shows the owner setup screen: enter your email, name and a strong password. The first person to complete it becomes the instance owner, so do this straight away.

> [!NOTE]
>
> The `n8n_data` volume holds the SQLite database and the encryption key for every credential you save in n8n. Never delete it without a backup.

## How to use Nginx instead of Traefik

If Nginx already serves other sites on ports 80 and 443, delete the whole `traefik` service and the `traefik_data` volume from `compose.yaml`. n8n already listens on `127.0.0.1:5678`, so proxy to it as in [set up Nginx as a reverse proxy](https://help.freakhosting.com/portals/other/how-to-set-up-nginx-as-a-reverse-proxy.md), including the WebSocket `Upgrade` headers, then run `sudo certbot --nginx -d n8n.example.com`. Add `N8N_PROXY_HOPS=1` to the n8n environment so it trusts the forwarded headers from one proxy.

## How to check it worked

```bash theme={null}
sudo docker compose ps
curl -sf http://127.0.0.1:5678/healthz
```

Both containers show `Up`, and `curl` exits without an error (add `-v` to see the `200` response). In the browser, the padlock shows a valid certificate.

## How to back up n8n

A complete backup is the `.n8n` folder, which lives in the `n8n_data` volume. With the default SQLite database, stop n8n first so the copy is consistent:

```bash theme={null}
cd ~/n8n-compose
sudo docker compose stop n8n
sudo docker run --rm -v n8n-compose_n8n_data:/data -v "$PWD":/backup alpine tar -czf /backup/n8n-data.tar.gz -C /data .
sudo docker compose start n8n
```

The volume name is the folder name plus `_n8n_data`; check it with `sudo docker volume ls`. To also export workflows and credentials as readable JSON into `local-files`:

```bash theme={null}
sudo docker compose exec n8n n8n export:workflow --backup --output=/files/backups/workflows/
sudo docker compose exec n8n n8n export:credentials --backup --output=/files/backups/credentials/
```

Credentials stay encrypted; you need the key from the `.n8n` folder to restore them. See the [n8n backup guide](https://docs.n8n.io/deploy/host-n8n/keep-n8n-running/backup-and-restore) and [back up Docker volumes](https://help.freakhosting.com/portals/other/how-to-back-up-docker-volumes.md).

## How to update n8n

Back up first, then pull the new image and recreate the containers:

```bash theme={null}
cd ~/n8n-compose
sudo docker compose pull
sudo docker compose up -d
```

Read the [n8n release notes](https://github.com/n8n-io/n8n/releases) before a major version. To stay on one version, pin a tag such as `n8nio/n8n:2.30.0` instead of `latest`.

## Frequently asked questions

### Why do webhooks show localhost or the wrong URL?

n8n builds webhook URLs from its settings. Check that `N8N_HOST`, `N8N_PROTOCOL` and `N8N_WEBHOOK_URL` (or `WEBHOOK_URL` before 2.30.0) match your public HTTPS address, then run `sudo docker compose up -d`.

### Can I use PostgreSQL instead of SQLite?

Yes. n8n recommends PostgreSQL for production instances with more users or workflows running around the clock. Set `DB_TYPE=postgresdb` and the `DB_POSTGRESDB_*` variables; the [n8n-hosting repository](https://github.com/n8n-io/n8n-hosting) has a ready-made example.

### How do I set up email for invites and password resets?

Set `N8N_EMAIL_MODE=smtp`, `N8N_SMTP_HOST`, `N8N_SMTP_PORT`, `N8N_SMTP_USER`, `N8N_SMTP_PASS` and `N8N_SMTP_SENDER` in the n8n environment and recreate the container. Without SMTP, users can't reset their own passwords.

### Why does Traefik fail to get a certificate?

The `A` record doesn't point to this server yet, or port 443 is blocked or used by another program. Check with `sudo docker compose logs traefik` and [check open ports on Linux](https://help.freakhosting.com/portals/other/how-to-check-open-ports-on-linux.md).

## Related guides

> [card] [VPS and dedicated server guides](https://help.freakhosting.com/portals/other/vps-and-dedicated-server-guides.md)
>
> Every guide in this section.

> [card] [Traefik with Docker](https://help.freakhosting.com/portals/other/how-to-set-up-traefik-with-docker.md)
>
> How the Traefik labels work.

> [card] [Docker Compose tutorial](https://help.freakhosting.com/portals/other/how-to-use-docker-compose.md)
>
> How compose.yaml works.

> [card] [Update Docker containers](https://help.freakhosting.com/portals/other/how-to-update-docker-containers.md)
>
> Pull new images safely.

> [card] [Secure Docker on a VPS](https://help.freakhosting.com/portals/other/how-to-secure-docker-on-a-vps.md)
>
> Protect the Docker socket and ports.

***

> [!NOTE]
>
> **Checked against the official [n8n self-hosting documentation](https://docs.n8n.io/deploy/host-n8n/install-options/use-a-cloud-provider/use-docker-compose)** on 4 November 2026 (image `n8nio/n8n`); `compose.yaml` validated with `docker compose config` on Ubuntu 24.04 LTS. Environment variable names can change between n8n versions.

> [!NOTE]
>
> ### Need Extra Help?
>
> If you encounter any issues, our support team is ready to assist:
>
> * **Live Chat:** Quick assistance via our website.
> * **Support Ticket:** [Open a Ticket](https://freakhosting.com/clientarea/submitticket.php)
> * **Discord:** [Join our Community](https://discord.gg/freakhosting)
> * **Email:** [support@freakhosting.com](mailto:support@freakhosting.com)

> [!TIP]
>
> ### Save on Your Hosting
>
> Ready to upgrade your hosting? Use code **KB20** at checkout for **20% off** your first order!

***

**Last Updated:** November 2026


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.