If you’re searching for “n8n docker compose”, you probably want a reproducible way to run n8n that survives restarts and upgrades.
This tutorial sets up n8n using Docker Compose with:
-
persistent data storage (so workflows/users don’t disappear)
-
a predictable upgrade path
-
a simple way to expose it on your Zo
What you’ll end up with
-
n8n running in Docker
-
a docker-compose.yml you can version-control
-
a data volume for n8n state
Prerequisites
-
A Zo (or any Linux server) where you can run commands in a terminal
-
Docker installed
- On Zo: if Docker isn’t installed yet, ask your AI to “install Docker and Docker Compose”, then continue
Step 1: Create a project folder
In your terminal:
mkdir -p ~/services/n8n cd ~/services/n8n
Step 2: Create a Docker Compose file
Create docker-compose.yml:
services: n8n: image: n8nio/n8n:latest restart: unless-stopped ports: - "5678:5678" environment: - N8N_HOST=localhost - N8N_PORT=5678 - N8N_PROTOCOL=http - WEBHOOK_URL=http://localhost:5678/ - GENERIC_TIMEZONE=UTC volumes: - n8n_data:/home/node/.n8n volumes: n8n_data:
Notes:
-
n8n_datais where n8n stores users, credentials, workflows, and execution data. -
Using a named volume keeps your state separate from the container image, so you can upgrade safely.
Step 3: Start n8n
docker compose up -d
Check that it’s running:
docker compose ps
View logs if something looks off:
docker compose logs -f --tail=200
Step 4: Open n8n in your browser
-
If you’re on Zo: visit
http://localhost:5678from within Zo’s browser environment. -
If you need a public URL: expose port
5678as a Zo Service (HTTP) and use the public endpoint it gives you.
Step 5: Set a real webhook URL (important)
Many n8n integrations rely on webhooks. If you access n8n via a public URL, update WEBHOOK_URL to match.
Example (replace with your real endpoint):
- WEBHOOK_URL=http://YOUR_PUBLIC_URL/
Then restart:
docker compose up -d
Step 6: Basic security you should not skip
If your n8n is reachable from the public internet:
-
Put it behind authentication.
-
Prefer HTTPS.
-
Restrict access where possible.
A minimal first step is enabling basic auth:
- N8N_BASIC_AUTH_ACTIVE=true - N8N_BASIC_AUTH_USER=change-me - N8N_BASIC_AUTH_PASSWORD=change-me-too
After changing environment variables, restart the container:
docker compose up -d
Step 7: Upgrading n8n
docker compose pull docker compose up -d
Your workflows persist because they’re stored in the volume.
Troubleshooting
n8n starts but can’t log in / missing workflows
-
Make sure the volume is attached (
n8n_data:/home/node/.n8n). -
Don’t delete volumes unless you intend to wipe state.
Port 5678 already in use
Change the host port:
ports: - "5679:5678"
Then restart.
Summary
You now have a clean Docker Compose setup for n8n with persistent storage and a straightforward upgrade process. If you want to productionise it further, the next steps are: HTTPS + a stable hostname + tighter access controls.