Newsletter image

Subscribe to the Newsletter

Join 10k+ people to get notified about new posts, news and tips.

Do not worry we don't spam!

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Search

GDPR Compliance

We use cookies to ensure you get the best experience on our website. By continuing to use our site, you accept our use of cookies, Privacy Policy, and Terms of Service.

n8n - Automation

How to Install n8n: Docker, npm, and Two Bundled AI Stacks

Five realistic ways to get n8n running, from a throwaway container to Postgres-backed Compose and two bundled AI stacks. Plus the settings that decide whether webhooks work behind a proxy.

There are five realistic ways to get n8n running, and the one you pick determines how much pain you feel later. A throwaway Docker container takes 30 seconds and loses everything on restart. A Compose file with Postgres takes ten minutes and survives reboots, upgrades, and backups. Two bundled stacks install n8n alongside a local model runtime in one command, at the cost of pulling in a lot of software you may not want.

This is part two of the n8n Automation Stack series. Part one covered what n8n is and the four concepts behind it. Here we get it installed properly, including the environment variables that decide whether your webhooks work behind a reverse proxy. Part three depends on getting that last part right.

The Five Paths Compared

PathSetup timeDatabaseBest for
Docker, throwaway30 secondsSQLite, discardedClicking around for the first time
Docker with a volume2 minutesSQLite, persistedPersonal use, homelab, single user
Compose with Postgres10 minutesPostgreSQLAnything you would be annoyed to lose
npm5 minutesSQLiteNode developers, custom node work
Bundled AI stackOne commandPostgreSQLYou want a local model runtime too

Path 1: Docker With a Volume

This is the right default for a single user. The only change from the throwaway command in part one is a named volume and dropping --rm:

docker volume create n8n_data

docker run -d --name n8n \
  -p 5678:5678 \
  -v n8n_data:/home/node/.n8n \
  docker.n8n.io/n8nio/n8n

Everything lives in that volume: the SQLite database, your credentials, and the encryption key. Back up the volume and you have backed up the instance.

Path 2: Docker Compose With Postgres

n8n defaults to SQLite. It supports PostgreSQL as the alternative, and MySQL and MariaDB were deprecated back in v1.0, so Postgres is the only real choice once you outgrow a single file.

Move to Postgres when you want concurrent writes, a backup story that is not a file copy, or queue mode later.

services:
  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: change_me
    volumes:
      - pg_data:/var/lib/postgresql/data

  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    ports:
      - "5678:5678"
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: change_me
      N8N_ENCRYPTION_KEY: put_a_long_random_string_here
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - postgres

volumes:
  pg_data:
  n8n_data:

Bring it up with docker compose up -d. One refinement worth knowing: n8n supports a _FILE suffix on individual variables, so DB_POSTGRESDB_PASSWORD_FILE can point at a file instead of putting the password in the Compose file.

Path 3: npm

Useful if you are writing custom nodes and want the code on your host rather than inside a container:

npm install n8n -g
n8n start

Data goes to ~/.n8n by default. You can move it with N8N_USER_FOLDER. You are responsible for the service manager, the Node version, and the upgrade path, which is why most people end up on Docker anyway.

Back Up the Encryption Key Before You Do Anything Else

This is the single highest-consequence detail on this page.

n8n encrypts stored credentials with a key. If you do not set N8N_ENCRYPTION_KEY, n8n generates a random one on first launch and writes it into the user folder. Restore your database onto a fresh instance without that key and every stored credential is unreadable. The workflows come back, the connections do not.

Set it explicitly from the start and store it wherever you keep secrets. Note also that key rotation exists but is gated behind N8N_ENV_FEAT_ENCRYPTION_KEY_ROTATION, and the docs describe it as a one-way change that wants a full database backup first. Getting it right on day one is much cheaper.

The Variables That Decide Whether Webhooks Work

Run n8n on localhost and everything works. Put it behind nginx, Caddy, or Apache with TLS, and webhooks start handing out URLs nobody can reach. The cause is always the same: n8n does not know its own public address.

VariableDefaultWhat it does
N8N_HOSTlocalhostHost name n8n believes it is served from
N8N_PORT5678Port it binds
N8N_PROTOCOLhttpProtocol it advertises
WEBHOOK_URLnonePublic webhook base URL when behind a proxy
N8N_EDITOR_BASE_URLnonePublic URL of the editor front end

For an instance served at https://automation.example.com, the working set looks like this:

N8N_HOST=automation.example.com
N8N_PROTOCOL=https
N8N_PORT=5678
WEBHOOK_URL=https://automation.example.com/
N8N_EDITOR_BASE_URL=https://automation.example.com/

TLS terminates at the proxy. n8n keeps speaking plain HTTP on 5678 behind it, and N8N_PROTOCOL=https only tells n8n what to advertise in the URLs it generates.

One more proxy setting matters, and it is the one that breaks part three of this series: response buffering must be off. n8n's MCP server transport uses Server-Sent Events, and a buffering proxy will hold the stream until it times out. In nginx that is proxy_buffering off; on the relevant location block.

Path 4: local-ai-packaged

If you want n8n and a local model runtime together, local-ai-packaged bundles n8n, Ollama, Postgres, Qdrant, and a few other services behind a single command. You get a working local RAG setup without wiring five containers yourself.

The trade-off is that you inherit the whole stack, including parts you may not use, and its upgrade cadence rather than n8n's. We walked through the full install, the hardware acceleration profiles, and a first local RAG agent in our local-ai-packaged guide.

Path 5: ODS

ODS takes the same idea further and installs a private AI server in one command, with hardware auto-detection choosing a model tier for you. n8n is one of the services it brings up, alongside llama-server, Open WebUI, Whisper, Qdrant, and SearXNG.

Pick this when the goal is a private AI server that happens to include automation, rather than an automation server that happens to include AI. Details, including what the installer actually does, are in our ODS write-up.

Lock It Down Before You Expose It

An n8n instance holds credentials for every service it touches. Treat it as one of the more sensitive boxes you run.

Do not publish port 5678 to the internet directly. Bind it to localhost or a private network and let the reverse proxy be the only public listener. In Compose that means 127.0.0.1:5678:5678 instead of 5678:5678.

Three settings are worth knowing about:

VariableDefaultWhy you care
N8N_SECURE_COOKIEtrueCookies only over HTTPS. The usual reason people turn this off is testing over plain HTTP. Turn it back on.
N8N_BLOCK_ENV_ACCESS_IN_NODEfalseOff by default, meaning expressions can read the host environment. Set it to true if anyone else edits workflows.
N8N_RESTRICT_FILE_ACCESS_TOnoneConfines filesystem access to directories you name.

That second one deserves emphasis. With the default setting, anyone who can edit a workflow can read your environment variables, which is where your database password lives.

Upgrading and Rolling Back

On Docker, an upgrade is a pull and a recreate:

docker compose pull
docker compose up -d

Two habits make this safe. Pin a specific image tag rather than tracking latest, so an upgrade is a deliberate act you can reverse by editing one line. And snapshot the database before a major version jump, because n8n runs schema migrations on start and those do not roll back cleanly.

Which Path Should You Pick

Running it for yourself on a homelab box: Docker with a volume. Anything other people depend on: Compose with Postgres, an explicit encryption key, and pinned tags. Writing custom nodes: npm. Already planning to run local models: one of the bundled stacks, which saves you a day of container wiring.

Whichever you choose, set N8N_ENCRYPTION_KEY now and put it somewhere you will still be able to find it in a year.

Sources and Further Reading

Next in the series: turning one of these workflows into an MCP tool an AI agent can call directly. If your instance sits behind a proxy, check proxy_buffering before you start.

Prev Article
What Is n8n? A Developer Introduction to Workflow Automation
Next Article
Turn an n8n Workflow Into an MCP Tool Your AI Agent Can Call

Related to this topic: