Back to Home
Automation

How to Install n8n Locally on Windows with Docker (Free, Unlimited)

A complete walkthrough for running n8n on your own Windows PC with Docker and PostgreSQL — no subscription, no execution limits, no data leaving your machine. Includes the errors I actually hit, how I fixed them, and your first working workflow.

n8n is an open-source workflow automation tool — think Zapier or Make, except you can run the whole thing yourself. The hosted version bills you per execution. The version you install on your own machine does not bill you at all: unlimited workflows, unlimited runs, every core node including the AI Agent nodes, and none of your data ever leaving your PC.

This is the exact setup I run on Windows 11 with 16 GB of RAM. It uses Docker to run two containers — n8n itself and a PostgreSQL database behind it — so the setup mirrors how you would deploy it on a real server. Total cost: zero. Expect it to take about half an hour, most of which is waiting on downloads.

Running n8n locally is not a limited trial version. It is the same software the paid cloud plan runs, with the billing meter removed and your data kept on your own disk.

What you need before starting

ComponentMinimumComfortable
OSWindows 10Windows 11
RAM4 GB free16 GB total system RAM
CPU2 cores4 cores
Storage20-25 GB free40 GB+ free on an SSD
InternetNeeded for setupAny stable connection

n8n itself is light. The reason 16 GB is the comfortable number is everything else you keep open next to it — Docker Desktop, VS Code, Android Studio, a browser with too many tabs. On 8 GB it runs, but you will feel it.

What actually gets installed

  • WSL2 — the Linux layer Windows needs so Docker can run Linux containers.
  • Docker Desktop — the container runtime. Free for personal use and small businesses.
  • Docker Compose — bundled with Docker Desktop; starts both containers with one command.
  • n8n Community Edition — pulled as a Docker image, so there is no separate installer.
  • PostgreSQL 16 — the database behind n8n, also just a Docker image.

Only the first two are things you install by hand. n8n and Postgres arrive automatically when you run the compose file in step 5.

Step 1 — Enable WSL2

Open PowerShell as Administrator (right-click the Start button, choose Terminal (Admin)) and run:

powershell
wsl --install

This installs WSL2 along with Ubuntu as the default Linux distribution. Restart when it asks you to. On the first boot Ubuntu will ask you to create a username and password — this is local to Ubuntu only and has nothing to do with your Windows login, but write it down anyway.

Step 2 — Install Docker Desktop

  • Download it from docker.com/products/docker-desktop.
  • Run the installer and leave "Use WSL 2 instead of Hyper-V" checked — it is the default.
  • Restart the computer once the installer finishes.
  • Docker Desktop starts on its own. Wait for the whale icon in the system tray to stop animating, which means the engine is fully up.

If Docker asks you to create an account and the signup fails with a server error, ignore it and click Skip. That failure is on Docker’s side and an account is not required for local use. Mine failed and the setup worked perfectly without one.

Step 3 — Fix the WSL integration conflict (if you hit it)

If Docker Desktop shows "WSL integration with distro Ubuntu-22.04 unexpectedly stopped", you have two Ubuntu distributions installed and both are fighting to integrate with Docker at once. It is a common state on machines that had WSL before.

  • Click "Skip WSL distro integration" on the error dialog to stop the immediate conflict.
  • Open Docker Desktop → Settings → Resources → WSL Integration.
  • Turn on "Enable integration with my default WSL distro".
  • In the list of additional distros, enable only Ubuntu. Leave Ubuntu-22.04 unchecked.
  • Click Apply & Restart.

If you only have one Ubuntu, you will never see this error — skip straight to step 4.

Step 4 — Verify Docker works

Do not skip this. It takes ten seconds and it separates "Docker is broken" from "my compose file is wrong" later on.

powershell
docker --version
docker run hello-world

You want the container to download and print "Hello from Docker!". If instead you get a TLS handshake timeout — which is what happened to me on a fresh install — do not go hunting through firewall settings. The cause is almost always a stale WSL2 network state left over from the install. Fix it with:

powershell
wsl --shutdown

Then reopen Docker Desktop, wait for the engine to come fully up, and run the hello-world command again. It worked on the first retry for me. Worth knowing while you debug this: a failed ping to registry-1.docker.io proves nothing, because ICMP is commonly blocked even when HTTPS is fine, and a 401 Unauthorized from that registry is the healthy response, not an error.

Step 5 — Create the project folder and compose file

powershell
mkdir C:\n8n-local
cd C:\n8n-local

Inside that folder create a file named docker-compose.yml with exactly this content. It defines the two services, wires them together, and gives each one a persistent volume so nothing is lost when you stop the containers.

yaml
services:
  postgres:
    image: postgres:16
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=n8n_password
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U n8n -d n8n']
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    restart: always
    ports:
      - "5678:5678"
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=n8n_password
      - N8N_SECURE_COOKIE=false
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  postgres_data:
  n8n_data:

Two details in there are worth understanding rather than just copying. The healthcheck plus depends_on means n8n waits until Postgres is genuinely accepting connections before it starts, instead of crash-looping for the first few seconds. And the two named volumes are why your workflows survive a restart — the containers are disposable, the volumes are not.

The password in this file is fine for a local-only instance. If you ever expose this beyond your own machine, change it and move it into an environment file first.

Step 6 — Start it up

powershell
docker compose up -d

The first run downloads both images, which takes a few minutes — they are large. After that, starting is nearly instant. The -d flag runs them in the background so you get your terminal back. Check that both came up:

powershell
docker compose ps

You should see n8n-local-postgres-1 as "Up (healthy)" and n8n-local-n8n-1 as "Up" with port 5678 mapped. If n8n is restarting in a loop, read its logs with docker compose logs -f n8n — the reason is almost always a typo in the database environment variables.

Step 7 — Open the interface and create your account

Open your browser at http://localhost:5678. This is the n8n interface, and it is the same URL every time from now on. On first visit you get a setup screen asking you to create an owner account with an email and password.

Read this part carefully: that account lives only inside your local Postgres container. It has nothing to do with n8n Cloud at app.n8n.cloud — different system, no shared login, no sync. There is also no "forgot password" email, because there is no server to send one. Save those credentials somewhere you will find them again.

After signing in, n8n offers a free Community Edition licence key by email. You can skip it — it unlocks enterprise features like SSO, advanced permissions and environments, none of which matter for personal or learning use. Everything you actually need is already unlocked.

Finding your way around

  • Overview is the landing page — every workflow you create is listed here.
  • Workflows is where you build. Hit "Create Workflow" to open a blank canvas.
  • Executions is the run history — every time a workflow fires, the full input and output of each node is recorded here. This is where you debug.
  • Credentials is where API logins are stored once and reused across workflows.
  • On the canvas, the + button on the top right opens the node panel, and clicking any node opens a three-panel view: INPUT on the left, the node settings in the middle, OUTPUT on the right.

That three-panel node view is the single most useful thing in the app. Almost every problem you will have comes down to the data arriving in INPUT not being shaped the way you assumed, and that panel shows you the truth immediately.

Your first workflow

One small workflow is enough to confirm the install works and to teach you the loop every n8n build follows: a trigger starts it, a node transforms the data, and you inspect what came out.

  • Click Create Workflow, then the + on the canvas.
  • Search for "Manual" and add the Manual Trigger — it just means the workflow runs when you click the button.
  • Click the + on the trigger’s right edge, search for "Edit Fields", and add the Edit Fields (Set) node.
  • Inside it, add a field: name it message, type String, value Hello from n8n.
  • Close the node and click Execute Workflow at the bottom of the canvas.

Both nodes turn green and the OUTPUT panel of the Edit Fields node shows your data:

json
[
  {
    "message": "Hello from n8n"
  }
]

That is the whole model. Data moves between nodes as a list of JSON items, each node reads what the one before it produced, and you reference values in later nodes with an expression like {{ $json.message }}. Every workflow you ever build in n8n — Gmail triggers, HTTP calls, AI agents, error handlers — is that same loop with more interesting nodes in the middle.

Save the workflow with Ctrl+S so it persists in Postgres, then go look at it in Executions. Seeing your own test run in the history is the fastest way to get comfortable with where to look when something later goes wrong.

Commands you will actually use

What you wantCommand
Start n8n and Postgresdocker compose up -d
Stop them (data is kept)docker compose down
Stop and wipe everythingdocker compose down -v
See what is runningdocker compose ps
Watch the n8n logsdocker compose logs -f n8n
Restart both containersdocker compose restart
Update to the latest n8ndocker compose pull, then docker compose up -d

All of these must be run from C:\n8n-local, because that is where the compose file lives. The one to be careful with is docker compose down -v — the -v deletes the volumes, which means every workflow and credential goes with them. Plain docker compose down is the safe way to shut n8n off when you are not using it.

Problems you are likely to hit

ProblemCauseFix
Docker account signup failsA server-side error on Docker’s endSkip it — no account is needed locally
"WSL integration unexpectedly stopped"Two Ubuntu distros integrating at onceEnable only one distro in WSL Integration settings
hello-world: TLS handshake timeoutStale WSL2 network state after installRun wsl --shutdown, restart Docker Desktop
localhost:5678 will not loadContainers not up yet, or n8n crash-loopingCheck docker compose ps, then the n8n logs
n8n restarts over and overWrong database credentials in the compose fileCompare the DB_POSTGRESDB_* values against the postgres service
Everything vanished after a restartContainers were removed with -vUse docker compose down without -v next time

Where this leaves you

You now have a private, unlimited automation environment on your own machine, backed by a real database, that costs nothing to run and keeps every byte of data local. The only money that ever enters the picture is if you later connect a paid LLM API for AI workflows — n8n itself stays free no matter how much you use it.

From here, the natural next steps are the HTTP Request node for calling real APIs, the Schedule Trigger for anything recurring, and the Webhook node for letting outside services start your workflows. But they all read the same way as the two-node workflow you just built, so start by breaking that one and fixing it — it is a faster teacher than any tutorial.