How to Update n8n Self-Hosted: Safe Upgrades for Docker Compose, Docker, and npm (2026)
Introduction
Updating self-hosted n8n is where most self-hosting horror stories start: a skipped backup, a jumped migration, a dead credential set. This guide shows the safe update path for all three install methods, Docker Compose, plain Docker, and npm, with the exact commands, the pre-update backup routine, and the rollback procedure from n8n’s own documentation. It is written for anyone already running n8n on their own server, and pairs with our guide to installing n8n on an Ubuntu VPS and our Docker Compose setup walkthrough if you set things up with our tutorials.
Quick answer
Back up workflows, credentials, and the database first. Docker Compose: docker compose pull, then docker compose up -d. Plain Docker: pull the new image and recreate the container. npm: npm update -g n8n. Then verify your version and test workflows.
Why updates deserve their own runbook
Three facts, current as of October 2026:
- Release cadence: n8n’s documentation states that the project “releases a new minor version most weeks,” with
stablefor production andbetafor the most recent release. On the day this article was tested, the docs listed stable 2.41.4 and beta 2.42.1. A server installed six weeks ago can easily be three or four minors behind, which is exactly the gap where migrations get risky. - A real, measured gap: our lab install was on n8n 2.40.7 while npm already listed 2.41.4 as latest on 2026-10-01, a two-minor gap in about a week of releases. Running
npm outdated n8nsurfaces this in one line, and it takes under five seconds, so there is no excuse for discovering your version gap mid-incident. - npm installs are on borrowed time: n8n’s install documentation now carries a warning that “npm-based installs are deprecated from n8n 3.0,” and starting n8n 2.40.7 outside a container prints: “Running n8n outside a container is deprecated. Future versions will require running n8n via the official Docker image.” (measured in our lab on 2026-09-30). If you still run n8n via npm, this update guide also tells you how to migrate the habit before version 3 forces it.
And the vendor line that sets the cadence. n8n’s official Update n8n page says: “Update frequently: this avoids having to jump multiple versions at once, reducing the risk of a disruptive update. Try to update at least once a month.” Everything below is built around that one sentence: small, frequent, deliberate updates with a backup you can actually restore.
Prerequisites
- A working self-hosted n8n install (Docker Compose, plain Docker, or npm) that you have root or sudo access to.
- Know your install method and current version before touching anything (Step 1 shows how).
- Enough disk space for a backup: at least 2x your database size plus your workflows export.
- Access to the n8n releases page to scan for breaking changes before you update.
- Ten quiet minutes with no critical workflows running.
Step 1, Identify your install method and current version
Updates are method-specific, and the number-one cause of failed updates is running Docker instructions against an npm install or vice versa. Run the checks for your setup:
# Every install method: what version is actually running?
n8n --version
# 2.40.7
# Docker Compose or plain Docker: which image tag is the container on?
docker images | grep n8n
# docker.n8n.io/n8nio/n8n 2.40.7 abc123def456 2 weeks ago
# npm (global install): is a newer version available?
npm outdated -g n8n
# Package Current Wanted Latest
# n8n 2.40.7 2.41.4 2.41.4
Write down the current version. You need it for the rollback command in Step 7. If npm outdated shows a Wanted newer than Current, an update is waiting for you, which was exactly the state of our lab on 2026-10-01: 2.40.7 installed, 2.41.4 wanted.
Step 2, Read the release notes for breaking changes
Before any update, scan the n8n releases on GitHub for the versions between yours and the target. You are looking for three things: breaking changes, database migrations (often phrased as “migrated X to Y”), and node renames or removals. n8n’s own update guide lists checking release notes as one of its three core tips, right next to updating frequently and testing in a staging environment.
Practical rule: if you are more than two minor versions behind stable, update in steps, one minor at a time, verifying startup after each. The official guidance warns against jumping multiple versions at once precisely because migrations are tested sequentially, not across arbitrary gaps. A jump from 2.38.x straight to 2.41.x is the classic way to produce the migration errors in the Troubleshooting section below.
Step 3, Back up everything before you touch the install
An update without a backup is a gamble, and backups are the one part of the process you cannot do after the fact. Do all four of these:
# 1. Export all workflows to files (run inside the n8n host or container)
n8n export:workflow --all --output=/root/n8n-backup/workflows/
# 2. Export credentials (this file contains secrets: chmod it and store it safely)
n8n export:credentials --all --output=/root/n8n-backup/credentials.json
chmod 600 /root/n8n-backup/credentials.json
# 3a. If you use Postgres (Docker Compose installs): full database dump
docker compose exec db pg_dumpall -U n8n > /root/n8n-backup/db-$(date +%F).sql
# 3b. If you use SQLite (npm installs): copy the live database file
cp ~/.n8n/database.sqlite /root/n8n-backup/database-$(date +%F).sqlite
# 4. Copy the .env file (or wherever N8N_ENCRYPTION_KEY lives)
cp ~/n8n-compose/.env /root/n8n-backup/env-$(date +%F).bak
Item 4 is the one people skip and regret. n8n encrypts every credential with N8N_ENCRYPTION_KEY; a database backup without the matching key is a database full of credentials you can never decrypt. Our Docker Compose guide explains this in the backup section, and it applies to every update here: key and database must travel together.
Step 4, Update a Docker Compose install
This is the official flow from n8n’s Docker install documentation, adapted for Compose:
# Navigate to the directory holding your docker-compose.yml
cd ~/n8n-compose
# If you pin the image tag (recommended), bump it first, e.g.:
# image: docker.n8nio/n8n:2.40.7 -> image: docker.n8n.io/n8nio/n8n:2.41.4
# Pull the new image
docker compose pull
# Stop the old containers
docker compose down
# Start on the new image; n8n applies database migrations automatically
docker compose up -d
# Confirm the new version is serving
sleep 20 && docker compose logs --tail=30 n8n | grep -i "version"
Two details matter. First, docker compose down stops containers but leaves named volumes intact, so your Postgres data and the n8n storage volume survive; never use docker compose down -v here, because -v deletes the volumes and with them your data. Second, watch the first startup logs: a successful migration prints lines about applying migrations and then the normal “n8n ready” output. If the container enters a restart loop instead, stop and read the Troubleshooting section before retrying.
Step 5, Update a plain Docker install
The official Docker update instructions use docker pull plus container recreation:
# Pull the new image (pin a version for production, avoid floating latest)
docker pull docker.n8n.io/n8nio/n8n:2.41.4
# Find and stop the old container
docker ps -a | grep n8n
docker stop n8n
docker rm n8n
# Recreate it with EXACTLY the same options you started it with,
# especially the volume mount and environment variables:
docker run -d --name n8n \
-p 5678:5678 \
-e GENERIC_TIMEZONE="Asia/Shanghai" \
-e TZ="Asia/Shanghai" \
-e DB_TYPE=postgresdb \
-e DB_POSTGRESDB_DATABASE=n8n \
-e DB_POSTGRESDB_HOST=postgres-host \
-e DB_POSTGRESDB_PORT=5432 \
-e DB_POSTGRESDB_USER=n8n \
-e DB_POSTGRESDB_PASSWORD=your-password \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n:2.41.4
The -v n8n_data:/home/node/.n8n mount is what carries your data across the recreation, so the new container starts with your old database, credentials, and settings file. Losing that flag is how people “update” into a factory-fresh empty n8n. If you originally started n8n with a long docker run line and no longer remember it, docker inspect n8n before stopping the old container shows every flag it was created with, so you can reconstruct the command exactly. n8n documents the pull and recreate sequence in its Install with Docker guide, including the docker ps -a, docker stop, docker rm, docker run steps.
Step 6, Update an npm install
The official npm update command from n8n’s docs is one line:
# Update a global install to the latest version
npm update -g n8n
# Or pin to a specific version (safer in production)
npm install -g n8n@2.41.4
# Then start n8n as usual
n8n start
I verified this path in our lab on 2026-10-01: a local npm install at 2.40.7 updated to 2.41.4 with npm update n8n in about six minutes (54 packages added, 40 removed, 112 changed), and n8n --version reported 2.41.4 afterward with no migration errors in the startup log. One honest caveat: the lab used a local install, while production npm installs are usually global (-g), so expect the global path to additionally need sudo or fixed npm permissions, covered in Troubleshooting.
Also note the deprecation context from the evidence section: npm installs are deprecated from n8n 3.0, so every npm update is also a good moment to plan the move to Docker. If you installed n8n with our Docker Compose guide you are already on the future-proof path.
Step 7, Verify the update and know the rollback
After the new version is up, verify before you declare victory:
# The running version matches what you pulled
n8n --version
# or: docker exec n8n n8n --version
# The editor loads, one workflow executes end to end
# Check Settings > Log or docker compose logs for migration errors
docker compose logs --tail=50 n8n | grep -iE "migration|error" | head
If something is broken and you need to go back, n8n documents the rollback in its npm install guide: install the older version again, then run n8n db:revert to roll back the database migration before starting:
# npm: reinstall the previous version, then revert the migration
npm install -g n8n@2.40.7
n8n db:revert
n8n start
# Docker Compose: point the image tag back, pull, recreate
# (edit compose file: image: docker.n8n.io/n8nio/n8n:2.40.7)
docker compose pull
docker compose down
docker compose up -d
Repeat n8n db:revert once per migration if the update applied several. And the honest limit: if the new version wrote data in a format the old migrations cannot undo, db:revert will not save you, which is why Step 3’s backup exists. Restore the database dump and the matching encryption key, and you are back to a known-good state no matter what.
Troubleshooting
1. n8n restarts in a loop with database migration errors
Symptom: after the update, the container logs show migration failures or the process exits during startup, and the editor never loads.
Cause: you jumped too many versions at once, and a migration in the chain failed against your database state. This is the failure mode n8n’s “update frequently” guidance exists to prevent.
Fix: restore your pre-update database backup, then update stepwise, one minor version at a time, confirming clean startup after each. If only one migration failed, try n8n db:revert on the new version and restart once more before restoring. Always read the release notes for the versions you skipped: they often document manual steps that the automatic migration cannot perform.
2. All credentials fail with decryption errors after the update
Symptom: workflows run, but every credential shows an error and API nodes fail authentication.
Cause: the N8N_ENCRYPTION_KEY changed or was not passed to the new container. Common trigger: recreating a Docker container without copying the -e N8N_ENCRYPTION_KEY=... flag, or generating a fresh key in a new .env file. Credentials encrypted with the old key cannot be decrypted with a new one, and n8n will not warn you before you discover this in production.
Fix: stop n8n, restore the original key from your backup (Step 3, item 4), and restart. If you use our compose setup, the key lives in .env next to the compose file; diff it against the backup before every update.
3. Webhooks and OAuth callbacks break after the update
Symptom: the editor works, but webhook URLs return 404s or OAuth connections fail with redirect URI mismatches.
Cause: WEBHOOK_URL or N8N_HOST no longer matches the public URL, often because the values were retyped during container recreation, or a reverse proxy changed while the n8n config did not. n8n registers webhook paths and OAuth redirect URIs from these variables at startup.
Fix: verify both variables against the actual public URL (https://n8n.yourdomain.com, no trailing slash), fix them in .env or the docker run flags, and restart n8n. Then re-test one webhook and one OAuth credential. This is the same class of misconfiguration our Ubuntu VPS install guide warns about during initial setup, and updates are the second most common time it appears.
4. npm update fails with EACCES permission denied
Symptom: npm update -g n8n dies with EACCES: permission denied on the global node_modules directory.
Cause: the global npm prefix is owned by root while you run as a normal user, the standard outcome of installing Node.js from a system package and npm packages without sudo.
Fix: either run the update with sudo npm update -g n8n, or fix npm’s directory permissions once per the official npm docs (reassign ~/.npm and the global prefix to your user), or switch to a Node version manager like nvm or fnm where the global prefix is user-owned. Pick one approach and stick with it; mixing sudo and non-sudo npm usage is how the permissions get tangled in the first place.
5. Community nodes or custom workflows break on a major version bump
Symptom: after a 1.x to 2.x style jump, community nodes fail to load or workflows using them error out.
Cause: n8n 2.0 changed the task runner architecture, and older community nodes built against 1.x internals are not always compatible. n8n’s docs note that N8N_RUNNERS_ENABLED is deprecated from 2.0 because task runners are now the default execution path.
Fix: update the community node packages to versions declaring n8n 2.x support, test the affected workflows in a staging copy first, and check the node’s GitHub repository for an open compatibility issue. If no fixed version exists, pin n8n at the last working minor until the node author catches up. For agent workloads specifically, our n8n vs Make comparison notes that node compatibility is one of the hidden costs of major version jumps.
FAQ
See the FAQ in the front matter above: six questions covering version checks, rollbacks, the latest tag, Postgres updates, update cadence, and updating during active executions.
Conclusion
A safe n8n update is a boring n8n update: read the release notes, back up workflows, credentials, database, and encryption key together, bump one version at a time with the command for your install method, and verify before you walk away. Do it monthly and you will never face the multi-version migration jumps that cause most update failures. If you are still on npm, treat each update as a reminder that Docker is the install path n8n is standardizing on. Next, harden the setup this update protects: our Docker Compose guide covers queue mode and backups, and our error handling tutorial shows how to make your workflows survive the incidents updates are meant to prevent.
Frequently asked questions
How do I check which version of n8n I am running?
Run n8n --version from the host where n8n is installed, or check the version shown in the n8n editor under Settings. For Docker installs, run docker images | grep n8n to see which image tag your container uses. For npm installs, npm outdated -g n8n shows the installed version next to the latest published version.
Can I roll back to an older n8n version after updating?
Yes, but with a condition. If the update applied a database migration, install the older version first, then run n8n db:revert to roll the database back before starting n8n again. This is the official rollback path from n8n's npm install documentation. For Docker, pull the older image tag and recreate the container. Always keep a pre-update backup of your database, because a migration that wrote data in a new format may not revert cleanly.
Should I use the latest Docker tag so n8n updates itself?
No. A floating latest tag means a single docker compose pull can jump several minor versions at once, which is exactly how failed migrations and broken community nodes happen. Pin the image tag to a specific version, such as docker.n8n.io/n8nio/n8n:2.41.4, read the release notes, then bump the tag deliberately. Our [Docker Compose setup guide](/n8n-docker-compose-setup/) covers the pinning practice in detail.
How often should I update self-hosted n8n?
At least once a month. n8n's own update guide says it directly: update frequently to avoid jumping multiple versions at once, because large jumps are where disruptive updates come from. n8n ships a new minor version most weeks, so a monthly cadence keeps you within one or two versions of stable.
Do I need to update Postgres or Redis when I update n8n?
Usually not. n8n updates independently of its database and queue services. Keep Postgres and Redis on their own stable tags and update them on a separate schedule. The one exception is when n8n's release notes raise the minimum supported database version, which has happened in past major releases, so checking the release notes before every n8n update is the habit that matters.
Is it safe to update n8n while workflows are running?
Stop executions first. In Docker Compose, docker compose down stops the stack gracefully, and in-flight executions are lost unless you wait for them to finish. For production instances, enable executions in queue mode with workers, drain them, then update. Never update during a critical scheduled run; pick a quiet window and confirm no executions are active in the editor first.