Files
MajorWiki/02-selfhosting/services/updating-n8n-docker.md
MajorLinux 87d63039af wiki: audit fixes — broken links, wikilinks, frontmatter, stale content (66 files)
- Fixed 4 broken markdown links (bad relative paths in See Also sections)
- Corrected n8n port binding to 127.0.0.1:5678 (matches actual deployment)
- Updated SnapRAID article with actual majorhome paths (/majorRAID, disk1-3)
- Converted 67 Obsidian wikilinks to relative markdown links or plain text
- Added YAML frontmatter to 35 articles missing it entirely
- Completed frontmatter on 8 articles with missing fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:16:29 -04:00

4.5 KiB

title, domain, category, tags, status, created, updated
title domain category tags status created updated
Updating n8n Running in Docker selfhosting services
n8n
docker
update
self-hosting
automation
published 2026-03-30 2026-03-30

Updating n8n Running in Docker

n8n's in-app update notification checks against their npm release version, which often gets published before the latest Docker Hub tag is updated. This means you may see an update prompt in the UI even though docker pull reports the image as current. Pull a pinned version tag instead.

Check Current vs Latest Version

# Check what's running
docker exec n8n-n8n-1 n8n --version

# Check what npm (n8n's upstream) says is latest
docker exec n8n-n8n-1 npm show n8n version

If the versions differ, the Docker Hub latest tag hasn't caught up yet. Use the pinned version tag.

Get the Running Container's Config

Before stopping anything, capture the full environment so you can recreate the container identically:

docker inspect n8n-n8n-1 --format '{{json .Config.Env}}'
docker inspect n8n-n8n-1 --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'

For MajorsHouse, the relevant env vars are:

N8N_EDITOR_BASE_URL=https://n8n.majorshouse.com/
N8N_PORT=5678
TZ=America/New_York
N8N_TRUST_PROXY=true
GENERIC_TIMEZONE=America/New_York
N8N_HOST=n8n.majorshouse.com
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.majorshouse.com/

Data volume: n8n_n8n_data:/home/node/.n8n

Perform the Update

# 1. Pull the specific version (replace 2.14.2 with target version)
docker pull docker.n8n.io/n8nio/n8n:2.14.2

# 2. Stop and remove the old container
docker stop n8n-n8n-1 && docker rm n8n-n8n-1

# 3. Start fresh with the new image and same settings
docker run -d \
  --name n8n-n8n-1 \
  --restart unless-stopped \
  -p 127.0.0.1:5678:5678 \
  -v n8n_n8n_data:/home/node/.n8n \
  -e N8N_EDITOR_BASE_URL=https://n8n.majorshouse.com/ \
  -e N8N_PORT=5678 \
  -e TZ=America/New_York \
  -e N8N_TRUST_PROXY=true \
  -e GENERIC_TIMEZONE=America/New_York \
  -e N8N_HOST=n8n.majorshouse.com \
  -e N8N_PROTOCOL=https \
  -e WEBHOOK_URL=https://n8n.majorshouse.com/ \
  docker.n8n.io/n8nio/n8n:2.14.2

# 4. Verify
docker exec n8n-n8n-1 n8n --version
docker ps --filter name=n8n-n8n-1 --format '{{.Status}}'

No restart of Caddy or other services required. Workflows, credentials, and execution history are preserved in the data volume.

Reset a Forgotten Admin Password

n8n uses SQLite at /home/node/.n8n/database.sqlite (mapped to n8n_n8n_data on the host). Use Python to generate a valid bcrypt hash and update it directly — do not use shell variable interpolation, as $ characters in bcrypt hashes will be eaten.

python3 -c "
import bcrypt, sqlite3
pw = b'your-new-password'
h = bcrypt.hashpw(pw, bcrypt.gensalt(rounds=10)).decode()
db = sqlite3.connect('/var/lib/docker/volumes/n8n_n8n_data/_data/database.sqlite')
db.execute(\"UPDATE user SET password=? WHERE email='marcus@majorshouse.com'\", (h,))
db.commit()
db.close()
db2 = sqlite3.connect('/var/lib/docker/volumes/n8n_n8n_data/_data/database.sqlite')
row = db2.execute(\"SELECT password FROM user WHERE email='marcus@majorshouse.com'\").fetchone()
print('Valid:', bcrypt.checkpw(pw, row[0].encode()))
"

Valid: True confirms the hash is correct. No container restart needed.

Why Arcane Doesn't Always Catch It

Arcane watches Docker Hub for image digest changes. When n8n publishes a new release, there's often a delay before the latest tag on Docker Hub is updated to match. During that window:

  • n8n's in-app updater (checks npm) reports an update available
  • docker pull latest and Arcane both report the image as current

Once Docker Hub catches up, Arcane will notify normally. For immediate updates, use pinned version tags as shown above.

Troubleshooting

Password still rejected after update: Shell variable interpolation ($2b, $10, etc.) silently truncates bcrypt hashes when passed as inline SQL strings. Always use the Python script approach above.

Container exits immediately after recreate: Check docker logs n8n-n8n-1. Most commonly a missing env var or a volume permission issue.

Webhooks not firing after update: Verify N8N_TRUST_PROXY=true is set. Without it, Caddy's X-Forwarded-For header causes n8n's rate limiter to drop webhook requests before parsing the body.

npm show n8n version returns old version: npm registry cache inside the container. Run docker exec n8n-n8n-1 npm show n8n version --no-cache to force a fresh check.