Intermediate 11 minn8n

n8n with Docker: install and self-host free of charge

n8n with Docker is the shortest path to a self-hosted automation instance that survives restarts and updates. This guide intentionally stops at the foundation: a Docker Compose file, a data volume, an encryption key you control, a backup and update procedure, and careful HTTPS exposure. AI nodes and connecting to Ollama are covered in a separate guide; here, the goal is a clean installation you won't have to redo.

By Samir K.·Update 2026-10-14·Tested on Windows, macOS, and Linux

#Why install n8n with Docker instead of npm

n8n is a Node.js application. You can run it with npm or npx, and the documentation suggests this for a quick trial. For an instance that runs continuously, the official Docker image is the approach recommended by the project: it includes the correct Node.js version, isolates n8n from the rest of the machine, and makes updates as simple as changing the image. This is also the format used by n8n's hosting documentation for all its server examples.

The second advantage is reproducibility. A docker-compose.yml file describes the entire configuration: image, port, environment variables, and data volume. You can version it, copy it to another machine, or review it six months later to know exactly what is running. With an npm installation, this information is scattered across the system, user profile, and service manager.

What this guide covers
Local or small-server installation, data persistence, encryption key, backup, updates, and HTTPS access.
What it does not cover
n8n's AI nodes, connecting to Ollama, the MCP server, and scaling in queue mode. The first two topics have their own guide, linked at the end of the article.
What we are not claiming
No installation duration, measured consumption, or fixed version number. These values change from one release to the next and should be checked in the official sources when you install.

#License and limitations of the community edition

The Local Agents Kit

Agents that act on your machine: agentic Cline, MCP, n8n + Ollama, local automations.

  • Lifetime online access
  • PDF + files
  • Refunded within 30 days

n8n is not open source under the OSI definition. The code is published under the Sustainable Use License, a model the publisher calls “fair-code.” Broadly speaking, you can use, modify, and host n8n freely for your internal, personal, or business needs. What is restricted is resale: offering n8n as a hosted service to third parties, or integrating it into a commercial product, requires an agreement with the publisher. The full text and FAQ are available at docs.n8n.io/sustainable-use-license/; read them if your use goes beyond internal automation.

The version you install with Docker is the community edition. It includes the full editor, hundreds of integration nodes, webhooks, scheduled triggers, AI nodes, and user management. Some features are reserved for paid self-hosted plans: single sign-on (SSO), environments with Git synchronization, external secrets, sending logs to an external tool, and some collaboration features. The publisher also offers a free key called “registered community,” obtained by providing an email address in the settings, which unlocks a few additional features. The exact list changes over time: the page docs.n8n.io/hosting/community-edition-features/ is authoritative.

i
Free, but not open source
For personal or internal use, the distinction makes no practical difference. It matters if you plan to resell a service built on n8n, or if your company requires an OSI-approved license: in that case, read the license before installing, not afterward.

#Prerequisites

Docker and Docker Compose
Docker Engine with the Compose plugin on Linux, or Docker Desktop on Windows and macOS. Check with docker compose version: the command must return a version number, using two words (docker compose), not the hyphenated command from the older tool.
A machine that stays powered on
n8n runs your workflows at the scheduled time or when a webhook is received. A PC that shuts down in the evening will miss overnight triggers. A mini PC, a Docker-compatible NAS, or a small VPS will work; memory requirements remain modest for a few simple workflows.
An available port
n8n listens on port 5678 inside the container. We publish it on the same number on the host; change it if another service is already using it.
For the HTTPS step only
A domain name pointing to the machine, with ports 80 and 443 reachable from the Internet. Without that, stick to local access or use a VPN: the HTTPS section covers both options.
Terminal
docker --version
docker compose version

#Install n8n with Docker Compose step by step

n8n's documentation first provides a one-line docker run command, which is useful for a trial. We go straight to Compose: the file is only slightly longer and becomes the reference for your installation. All values below are documented by n8n; only the time zone and port values are choices made in this guide.

  1. 01
    Create the project folder
    A dedicated directory contains the Compose file, the .env file, and later your backups. n8n's data itself goes into a named Docker volume, not this directory.
  2. 02
    Generate the encryption key
    Before the first startup, generate a random key and place it in the .env file. The next section explains why this order matters.
  3. 03
    Write docker-compose.yml
    Copy the file below. It publishes n8n on port 5678 of the machine, restricted to the local address 127.0.0.1, and mounts the n8n_data volume to the container's /home/node/.n8n directory, where n8n stores its SQLite database, configuration, and files.
  4. 04
    Get started
    docker compose up -d télécharge l'image et lance le conteneur en arrière-plan. La première exécution prend le temps du téléchargement de l'image; les suivantes sont immédiates.
  5. 05
    Create the owner account
    Open http://localhost:5678 in a browser. n8n asks you to create the first account, which becomes the instance owner. Since version 1.0, this account protects access; the old basic authentication through environment variables no longer exists.
Terminal
mkdir -p ~/n8n && cd ~/n8n

# Clé de chiffrement : 64 caractères hexadécimaux
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)" > .env
chmod 600 .env
cat .env
docker-compose.yml
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=Europe/Paris
      - TZ=Europe/Paris
      - N8N_RUNNERS_ENABLED=true
      - N8N_DIAGNOSTICS_ENABLED=false
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=336
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:
Terminal
docker compose up -d
docker compose logs -f n8n   # Ctrl+C pour quitter les journaux

A few notes on the variables. GENERIC_TIMEZONE sets the time zone used by the Schedule Trigger node and date expressions; TZ aligns the system clock inside the container. N8N_RUNNERS_ENABLED activates task runners, the mechanism that executes Code node code in a separate process; the documentation recommends it, and recent versions display a warning if it is missing. N8N_DIAGNOSTICS_ENABLED=false disables sending telemetry data to the publisher. The two EXECUTIONS_DATA_* variables tell n8n to purge execution history older than 336 hours, or fourteen days, to prevent the database from growing indefinitely.

The ./local-files:/files mount is optional. It gives n8n a folder shared with the host machine, which is useful for nodes that read or write files. Remove the line if you do not need it.

→
Access from another machine on the local network
The file publishes the port on 127.0.0.1: only the machine hosting n8n can access it. To open access to your local network, replace it with "5678:5678" and add N8N_SECURE_COOKIE=false to the variables; otherwise, n8n rejects HTTP connections from an address other than localhost with an explicit secure-cookie message. This variable must never remain in place on an instance exposed to the Internet: use the HTTPS section.

#The encryption key: the variable you must not lose

n8n encrypts all credentials you save in the interface, including API tokens, passwords, and OAuth keys for your integrations. The encryption key used is N8N_ENCRYPTION_KEY. If you do not define it, n8n generates one on the first startup and writes it to the config file in /home/node/.n8n, which is therefore stored in the volume. This works, but the key then exists only in that volume: if you lose it or recreate the instance without it, every credential becomes unreadable and must be entered again.

That is why this guide sets the key in the .env file before the first launch. It remains under your control, is backed up with the Compose file, and lets you restore the database on another machine without losing credentials. Two rules follow from this.

Never change the key afterward
A key different from the one used for encryption makes all existing credentials unusable. If you need to replace it, first export your decrypted credentials with the export:credentials command, then reimport them after the change.
Back up the .env file separately
Keep a copy of the key in your password manager. A volume backup without the key is useless for credentials, even if the workflows remain readable.
!
Key set after an initial startup without one
If you already started n8n without N8N_ENCRYPTION_KEY, the container contains an automatically generated key. Setting a different value in .env afterward triggers a startup error or makes the credentials unreadable. In that case, retrieve the existing key with docker exec n8n cat /home/node/.n8n/config and put that value in .env instead of generating a new one.

#Data persistence and backup

Everything n8n needs to retain lives in /home/node/.n8n: the SQLite database containing workflows, encrypted credentials, and execution history; the config file; installed community nodes; and binary files in disk-storage mode. The named volume n8n_data survives docker compose down and container removal. It does not survive docker compose down -v or docker volume rm: both commands delete the data.

For backups, two approaches complement each other. The first archives the entire volume: stop n8n while copying the files to avoid capturing a SQLite database mid-write. The second uses n8n's command-line tool to export workflows and credentials as JSON, which can be read and reimported individually.

Back up the entire volume
cd ~/n8n
mkdir -p backups
docker compose stop n8n
docker run --rm \
  -v n8n_data:/data:ro \
  -v "$PWD/backups":/backup \
  alpine tar czf "/backup/n8n_data-$(date +%F).tgz" -C /data .
docker compose start n8n
ls -lh backups/
JSON export using the n8n CLI
# Un fichier par workflow, puis un par identifiant, dans le volume
docker exec n8n n8n export:workflow --backup --output=/home/node/.n8n/exports/workflows/
docker exec n8n n8n export:credentials --backup --output=/home/node/.n8n/exports/credentials/

# Récupérer les exports sur la machine hôte
docker cp n8n:/home/node/.n8n/exports ./backups/exports-$(date +%F)

The --backup option for export commands groups the options that produce a readable file per item. Exported credentials remain encrypted with your key unless you add --decrypted; in that case, treat the file as a secret. To restore them, the import:workflow and import:credentials commands accept the same directory with the --separate option. The complete CLI reference is at docs.n8n.io/hosting/cli-commands/.

For a complete restore on another machine: recreate the directory with the same docker-compose.yml and the same .env, create the empty volume with docker compose up -d and then docker compose stop, extract the archive into the volume using the reverse of the backup command, and restart. The same encryption key is required to recover the credentials.

i
SQLite or PostgreSQL?
SQLite is the default database and is sufficient for a personal instance or a small team. The n8n documentation recommends PostgreSQL for production, especially once multiple workflows run in parallel or you plan to use queue mode. The switch uses the DB_TYPE=postgresdb and DB_POSTGRESDB_* variables, with a postgres service added to the Compose file. Migrating from SQLite to PostgreSQL involves the export and the import CLI described above.

#Update n8n without breaking the instance

n8n releases versions frequently. The image's latest tag points to the latest stable version, next points to the test version, and numbered tags pin a specific version. With Compose, updating takes three commands: pull the new image, stop the old container, and recreate one with the same configuration. The data remains in the volume and is not touched. Database schema migrations, when needed, run automatically at startup.

Terminal
cd ~/n8n

# 1. Sauvegarde avant toute mise à jour (voir section précédente)

# 2. Mise à jour
docker compose pull
docker compose down
docker compose up -d

# 3. Contrôle
docker compose logs --tail=50 n8n
docker exec n8n n8n --version

Three precautions prevent most unpleasant surprises. Back up first: a database migration cannot be rolled back. Read the release notes at github.com/n8n-io/n8n/releases and the documentation's update page at docs.n8n.io/hosting/installation/updating/: major versions remove environment variables or change default behavior, and the documentation maintains a dedicated page for breaking changes. Finally, if the instance is important to you, prefer a numbered tag over latest: you choose when to upgrade instead of being forced to do so on the next pull.

docker-compose.yml (pinned version, format example)
services:
  n8n:
    # Remplacez par un numéro lu sur la page des releases
    image: docker.n8n.io/n8nio/n8n:1.XX.Y
→
Go back
If a version causes problems, put the previous tag back in the Compose file and run docker compose up -d again. This works as long as the new version hasn't migrated the database schema; otherwise, restore the backup made before the update. That's why step 1 matters.

#Expose n8n over HTTPS, carefully

As long as you use n8n from the machine hosting it or from your local network, the previous setup is sufficient. Exposure becomes necessary for webhooks: a third-party service that needs to call your instance, or access from outside. There are two ways to proceed, and the first is often the right one.

A VPN instead of exposure
Tailscale, WireGuard, or your router's VPN let you access n8n from anywhere without opening a port to the Internet. For personal use without a public webhook, this is the safest and simplest solution. The instance remains on HTTP within the private network, and N8N_SECURE_COOKIE=false becomes necessary if you access it through the VPN address.
A reverse proxy with a certificate
To receive public webhooks, you need a domain name, a reverse proxy that terminates TLS, and a certificate. n8n's official example uses Traefik; we show Caddy, whose configuration fits in three lines and which obtains Let's Encrypt certificates on its own.

In the configuration below, n8n no longer publishes any ports: only Caddy is reachable on 80 and 443, and it forwards requests to the n8n container over Compose's internal network. The N8N_HOST, N8N_PROTOCOL, and WEBHOOK_URL variables tell n8n the public address where it is served; without them, the webhook URLs shown in the editor would point to localhost and OAuth redirects would fail.

docker-compose.yml (with Caddy)
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_HOST=n8n.votre-domaine.fr
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.votre-domaine.fr/
      - GENERIC_TIMEZONE=Europe/Paris
      - TZ=Europe/Paris
      - N8N_RUNNERS_ENABLED=true
      - N8N_DIAGNOSTICS_ENABLED=false
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=336
    volumes:
      - n8n_data:/home/node/.n8n

  caddy:
    image: caddy:2
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config

volumes:
  n8n_data:
  caddy_data:
  caddy_config:
Caddyfile
n8n.votre-domaine.fr {
    reverse_proxy n8n:5678
}

Before running docker compose up -d, the DNS record for n8n.votre-domaine.fr must point to the machine's public address, and ports 80 and 443 must be forwarded to it. Caddy then requests a certificate from Let's Encrypt and renews it without intervention. The caddy_data and caddy_config volumes preserve certificates and state across restarts.

!
What public exposure entails
An n8n instance reachable from the Internet is a target: it holds your integration credentials and can execute code. Use a long, unique password for the owner account, enable two-factor authentication in the settings, apply updates promptly, and leave no residual HTTP access. If you don't need public webhooks, a VPN remains preferable. The principles detailed in our guide to securing a Ollama server apply to n8n in the same way.

#Troubleshooting: common blockers

Secure cookie message on startup
You are accessing n8n over HTTP from an address that is not localhost. Either switch to HTTPS or add N8N_SECURE_COOKIE=false, only on a private network.
Permission error on /home/node/.n8n
The container runs as the node user, not root. This happens when you replace the named volume with a host directory whose permissions don't match. Keep the named volume, or set the directory owner to user ID 1000, which is node's ID in the image.
Scheduled workflows run at the wrong time
GENERIC_TIMEZONE is missing or misspelled. The expected value is an IANA time zone name such as Europe/Paris. Each workflow can also set its own time zone in its settings.
Webhooks display a localhost address
WEBHOOK_URL is not defined or does not match the address through which the third-party service reaches you. The value must end with a slash and include the protocol.
The database keeps growing
Execution cleanup is disabled or takes too long. Check EXECUTIONS_DATA_PRUNE and EXECUTIONS_DATA_MAX_AGE, and also consider the option that retains data from successful executions, which can be disabled workflow by workflow.
After an update, n8n refuses to start
Read the log with docker compose logs n8n: the message usually indicates a removed variable or a failed migration. Compare it with the release notes, then restore the backup if necessary.
n8n can't see Ollama on the same machine
From inside a container, localhost refers to the container itself, not the host. The address to use depends on the system and how Ollama is launched; that is the subject of the n8n guide and Ollama cited below.
Useful commands
docker compose ps                     # état du conteneur
docker compose logs --tail=100 n8n   # dernières lignes du journal
docker exec n8n n8n --version         # version installée
docker volume inspect n8n_n8n_data    # emplacement réel du volume (préfixe = nom du dossier)
docker compose restart n8n            # redémarrage simple

For questions not answered in the documentation, the community.n8n.io forum is active and the vendor responds there. Include the exact version, installation method, and log lines: these are the first three things they ask for.


#Go further

The instance is up, backed up, and up to date. The logical next step is to connect it to a local model and then integrate it into a larger stack. Official sources consulted for this guide: the hosting section of the n8n documentation (docs.n8n.io/hosting/), the Docker installation page (docs.n8n.io/hosting/installation/docker/), the update page, the license page, and the page about community edition features. These pages change with new versions: if they diverge from this guide, they are authoritative.

n8n + Ollama: automate with 100% local AI
The follow-up guide: AI nodes, connecting to Ollama from the container, and your first translation and summarization workflows. https://quelllm.fr/guide/n8n-ollama-automatisation-workflow
Ollama with Docker
If you also want to run Ollama in a container alongside n8n, with GPU access. https://quelllm.fr/guide/ollama-docker-installation-guide
Deploy an LLM in production with Docker Compose
The complete stack Ollama, Open WebUI, Qdrant, n8n, and Traefik in a single Compose file, taking you beyond an isolated instance. https://quelllm.fr/guide/deployer-llm-docker-compose-production
Secure your Ollama server
Authentication, firewall, reverse proxy: exposure rules apply to every self-hosted service, including n8n. https://quelllm.fr/guide/securiser-serveur-ollama
Did this guide help you?

Feedback, an error, or a clarification? Let us know—it improves the guide for everyone.