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.ymlyou can version-controla 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.