
Step by Step Guide to solve n8n Docker Installation Error
The first time I set up n8n on Docker, the container started, ran for 3 seconds, then silently disappeared. No crash banner. No error popup. Just docker ps showing nothing. Most devs get stuck at exactly this point – because Docker gives you almost no feedback when n8n exits quietly. If that’s where you are right now, this guide covers every error that causes it.
Who this is for: System administrators and developers who want to run n8n in Docker on Linux, macOS, or Windows (WSL2) and need a reliable, production‑ready setup. We cover this in detail in the n8n Installation Errors Guide.
Quick Diagnosis
- Docker daemon: Run
docker info. If it fails, start Docker or add your user to thedockergroup. - Pull the image:
docker pull n8nio/n8n:latest. Resolve “manifest not found” or “pull access denied” by confirming the tag or fixing network/proxy settings. - Set up a persistent volume: Create a host directory and match its ownership to the container UID (default 1000).
- Start the container: Use explicit flags (see the “Run n8n” snippet below).
- Inspect failures:
docker logs n8nreveals missing env vars, DB issues, or permission problems.
Debug Decision Tree – What’s Your Exact Error?
Run docker logs n8n immediately after your container exits. Copy the first error line and match it below — each branch takes you directly to the right fix.
Container exits immediately (docker ps shows nothing)?
↓ Run: docker logs n8n
├── EACCES: permission denied, open ‘/home/node/.n8n/config’
│ → UID mismatch on mounted volume → Fix: Section 3.3
├── Error: listen EADDRINUSE :::5678
│ → Port 5678 already taken → Fix: Section 3.6 (Port Conflict)
├── Killed / exit code 137
│ → Out of memory (OOM kill) → Fix: Section 3.7 (Memory / Swap)
├── Error: connect ECONNREFUSED 127.0.0.1:5432 (or :3306)
│ → DB env vars missing or wrong host → Fix: Section 3.5 log table
├── manifest unknown / pull access denied
│ → Wrong image tag or network block → Fix: Section 3.2
├── ENOENT: no such file or directory, open ‘/home/node/.n8n/…’
│ → Volume not mounted → Fix: Section 3.3
└── Cannot connect to the Docker daemon
→ Docker not running or user not in docker group → Fix: Section 3.1
Pro tip: If
docker logs n8nreturns nothing, the container crashed before n8n even started. That almost always means exit code 137 (OOM) or a missing required env var. Jump to Section 3.7 first.
1. Why Docker‑Based n8n Installations Fail?
If you encounter any npm installation failure n8n resolve them before continuing with the setup.
| Symptom | Typical Root Cause |
|---|---|
| Cannot connect to the Docker daemon | Docker service not running or user not in docker group |
| pull access denied / manifest unknown | Wrong image tag, network block, or Docker Hub rate‑limit |
| permission denied while mounting volume | Host directory ownership mismatches UID/GID inside container |
| Container exits immediately | Missing required env vars, DB connection errors, corrupted config |
| ENOENT: no such file or directory, open ‘/home/node/.n8n/…’ | Volume not created or path typo in -v flag |
EEFA (Error‑Explanation‑Fix‑Action) starts with reading the exact error message.
2. Prerequisites – Ensure a Healthy Docker Environment
If you encounter any windows installation error n8n resolve them before continuing with the setup.
Micro‑summary: Verify Docker version, resources, and network before pulling the image.
- Docker Engine ≥ 20.10 (older versions have networking bugs).
- Minimum 512 MiB RAM; allocate more for heavy workflows.
- Network access to Docker Hub:
curl -I https://registry-1.docker.io/v2/
EEFA note: Corporate proxies require
HTTP_PROXY/HTTPS_PROXYfor Docker. Missing proxy settings often surface as “pull access denied”.
3. Step‑by‑Step Fixes
3.1. Verify Docker Daemon & Permissions
# Check daemon status systemctl status docker # Start if inactive sudo systemctl start docker # Add current user to docker group (requires re‑login) sudo usermod -aG docker $USER newgrp docker # apply without logout
EEFA: Adding a user to the
dockergroup grants root‑equivalent privileges; ensure this aligns with your security policy.
3.2. Pull the n8n Image Manually
docker pull n8nio/n8n:latest
– manifest unknown → Tag does not exist. Use a specific version, e.g., n8nio/n8n:1.38.0.
– pull access denied → Check firewall or Docker Hub rate‑limit (unauthenticated pulls limited to 100 req/hr). Authenticate if needed:
docker login
3.3. Prepare a Persistent Volume
# Choose a host directory N8N_DATA="/home/$USER/n8n" mkdir -p "$N8N_DATA" # Align ownership with container user (UID 1000) sudo chown 1000:1000 "$N8N_DATA"
EEFA: If you run the container with a custom
USER_ID, replace1000with that UID.
Still seeing EACCES after chown? This is the full error stack you’ll see in docker logs n8n when the UID fix hasn’t been applied yet:
Error: EACCES: permission denied, open '/home/node/.n8n/config'
at writeFileSync (node:fs:2425:20)
at InstanceSettings.save (.../n8n-core/src/instance-settings/instance-settings.ts:241:16)
at InstanceSettings.loadOrCreate (.../n8n-core/src/instance-settings/instance-settings.ts:218:8)
at new InstanceSettings (.../n8n-core/src/instance-settings/instance-settings.ts:67:24)
Root cause: n8n runs as UID 1000 inside the container. If your host directory was created as root (e.g., with sudo mkdir), the container user has no write access. The fix:
# If chown on the folder alone doesn't work, use recursive: sudo chown -R 1000:1000 /path/to/your/n8n/data # Or run the container as your current user instead: docker run -d \ --name n8n \ --user $(id -u):$(id -g) \ -p 5678:5678 \ -v "$N8N_DATA:/home/node/.n8n" \ n8nio/n8n:latest
3.4. Run n8n with Diagnostic Flags
Part 1 – Core runtime options
docker run -d \ --name n8n \ -p 5678:5678 \ -v "$N8N_DATA:/home/node/.n8n"
Part 2 – Security & restart policy
docker run -d \ -e N8N_BASIC_AUTH_ACTIVE=true \ -e N8N_BASIC_AUTH_USER=admin \ -e N8N_BASIC_AUTH_PASSWORD=strongpassword \ --restart unless-stopped \ n8nio/n8n:latest
Common pitfalls
| Flag | Mistake | Fix |
|---|---|---|
| -p | Swapped host:container ports | Use -p 5678:5678 (host first) |
| -v | Relative path without $PWD |
Use absolute path or ${PWD} |
| -e env vars | Misspelled variable name | Verify against n8n docs (N8N_HOST, N8N_PORT) |
3.5. Diagnose a Failing Container
docker logs n8n # view stdout/stderr docker exec -it n8n sh # optional shell inside container
| Log snippet | Interpretation | Fix |
|---|---|---|
| Error: ENOENT: no such file or directory, open ‘/home/node/.n8n/.env’ | Volume not mounted or wrong path | Verify -v flag and host directory existence |
| Error: connect ECONNREFUSED 127.0.0.1:3306 | DB connection missing (MySQL) | Set DB_TYPE, DB_MYSQL_HOST, DB_MYSQL_PORT, DB_MYSQL_DATABASE, DB_MYSQL_USER, DB_MYSQL_PASSWORD env vars |
| Permission denied: ‘/home/node/.n8n’ | UID mismatch | chown host directory to container UID or run container with --user $(id -u):$(id -g) |
3.6. Fix: Port 5678 Already in Use
I’ve seen this trip up more devs than almost any other error — especially on VPS instances that already run other Node.js apps. n8n defaults to port 5678. If something else is already listening there, Docker silently fails to bind and the container exits.
Identify what’s holding port 5678:
# Linux / macOS sudo lsof -i :5678 # Windows netstat -ano | findstr :5678
Option A – Kill the conflicting process:
# Find the PID from lsof output, then: sudo kill -9 <PID>
Option B – Remap n8n to a different host port (preferred for production):
docker run -d \ --name n8n \ -p 8080:5678 \ # host port 8080 → container port 5678 -v "$N8N_DATA:/home/node/.n8n" \ n8nio/n8n:latest
n8n will now be accessible at http://localhost:8080 while still running internally on 5678. If you use NGINX, update your proxy_pass to point to http://localhost:8080.
EEFA: The log message for this error is
Error: listen EADDRINUSE :::5678. If you see this, port remapping is always the faster fix — don’t waste time hunting down the conflicting process unless you know what it is.
3.7. Fix: Container Killed – Exit Code 137 (Out of Memory)
Exit code 137 means the Linux kernel’s OOM (Out of Memory) killer terminated your container. This is extremely common on 1GB VPS instances — n8n plus Node.js plus SQLite can easily exceed that during startup. The container just disappears with docker logs n8n showing nothing, or a single line: Killed.
Confirm it’s an OOM kill:
docker inspect n8n --format='{{.State.OOMKilled}}'
# Returns: true
Fix A – Add swap memory (best option for cheap VPS):
# Create a 2GB swapfile sudo fallocate -l 2G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # Make it permanent across reboots echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
Fix B – Set a memory limit so Docker doesn’t consume everything:
docker run -d \ --name n8n \ --memory="768m" \ --memory-swap="1536m" \ -p 5678:5678 \ -v "$N8N_DATA:/home/node/.n8n" \ n8nio/n8n:latest
Fix C – In docker-compose.yml:
services:
n8n:
image: n8nio/n8n:latest
deploy:
resources:
limits:
memory: 768M
EEFA: For production n8n, the minimum recommended RAM is 2GB. If you’re on a 1GB VPS and adding swap still causes instability, switch to SQLite-only mode (no external DB), reduce
EXECUTIONS_DATA_SAVE_ON_SUCCESS=noneto limit writes, and avoid running more than 5 concurrent workflows.
4. Checklist – Did You Cover All Bases?
- [ ] Docker daemon running and current user in
dockergroup - [ ] Latest n8n image pulled without errors
- [ ] Host volume created, owned by UID 1000 (or custom UID)
- [ ] All required environment variables set (
N8N_HOST,N8N_PORT, DB vars if using external DB) - [ ] Container started with
--restart unless-stoppedfor production resilience - [ ] Logs inspected for any immediate crash reasons
- [ ] Port 5678 confirmed free (or remapped to alternate host port)
- [ ] Available RAM ≥ 1GB or swap enabled (to avoid exit code 137)
5. Advanced: Running n8n Behind a Reverse Proxy (NGINX)
Micro‑summary: Configure NGINX to forward HTTPS traffic to the n8n container and set matching environment variables.
5.1. Set Proxy‑Aware Environment Variables
docker run -d \ -e N8N_HOST="n8n.example.com" \ -e N8N_PORT=5678 \ -e N8N_PROTOCOL="https" \ ... (other flags) ...
5.2. Minimal NGINX Server Block
Server definition
server {
listen 443 ssl;
server_name n8n.example.com;
TLS configuration (replace with your certs)
ssl_certificate /etc/ssl/certs/your.crt;
ssl_certificate_key /etc/ssl/private/your.key;
Location proxy
location / {
proxy_pass http://localhost:5678;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
EEFA:
proxy_set_header X-Forwarded-Protomust match theN8N_PROTOCOLvalue; mismatches cause CSRF errors.
6. Verifying a Healthy Installation
# Container must be "running" docker ps -f name=n8n
# HTTP health check – expect 200 OK curl -I http://localhost:5678/healthz
Expected response header excerpt:
HTTP/1.1 200 OK content-type: application/json; charset=utf-8
A 503 response indicates missing env vars or DB connectivity—re‑inspect the logs.
7. Frequently Asked Questions
| Question | Short Answer |
|---|---|
| Can I use Docker Desktop on Windows? | Yes. Use the Linux container backend (or WSL2) and run the same commands in PowerShell or WSL2. |
Why does docker run exit with code 137? |
OOM kill – allocate more memory (--memory 1g) or add swap. See Section 3.7 for the full fix. |
Do I need to set N8N_BASIC_AUTH_ACTIVE? |
For production, absolutely. It prevents unauthenticated access to your workflows. |
| How to upgrade n8n? | Pull the new image, stop & remove the old container, then start a new one with the same volume: |
| n8n works on my Mac/local but not in Docker on Linux / CI? | UID mismatch. On Mac, Docker Desktop auto-handles volume permissions. On Linux, you must explicitly chown 1000:1000 your data directory. On Windows WSL2, store your data inside WSL (/home/user/n8n), not on the Windows drive (/mnt/c/...) — cross-filesystem volume mounts cause random permission failures. |
My container shows “running” but localhost:5678 returns nothing? |
n8n may still be starting (takes 10–15 seconds on first run). Wait and retry. If still unreachable, check your firewall (ufw status on Ubuntu) and confirm the port mapping with docker ps — the PORTS column must show 0.0.0.0:5678->5678/tcp. |
docker pull n8nio/n8n:latest docker stop n8n && docker rm n8n # rerun the docker run command from section 3.4
9. Next Steps
- Secure n8n with HTTPS – learn TLS termination in NGINX or Traefik.
- Scaling n8n with Docker Swarm – run multiple replicas behind a load balancer.
- Persisting workflow data in external PostgreSQL – avoid the default SQLite file for high‑availability setups.
*Follow the links above for deeper dives.*



