n8n Updates & Rollbacks | How to Update Safely Without Breaking Workflows
n8n updates come out regularly — new features, bug fixes, security patches. But every update is a risk. Learn version pinning, safe update procedures, and rollback strategies.
n8n updates come out regularly — new features, bug fixes, security patches. But every update is a risk. One bad version can break your workflows.
If your docker-compose.yml just says n8nio/n8n without a version, every pull grabs the latest. Convenient, but if an update breaks something, you can't easily go back.
With a pinned version, rollback is one command away.
In this guide, you'll learn:
- The pre-update checklist (3 essential steps)
- Version pinning vs
:latesttag - How to perform a live update
- How to rollback when things go wrong
- The nuclear option: full restore from backup
Prerequisites: This is Part 4 of my n8n series. Make sure you have backups set up from Part 3 before updating.
Pre-Update Checklist
Before ANY update, do these three things. Every time.
Step 1: Take a Backup
Run your backup script from Part 3:
/opt/n8n/backup.sh
Expected output:
Backup completed: /opt/n8n/backups/n8n-backup-20251216-143022.tar.gz
Verify the backup was created:
ls -la /opt/n8n/backups/
-rw-r--r-- 1 root root 52K Dec 16 14:30 n8n-backup-20251216-143022.tar.gz
If something breaks, you can restore everything. This is non-negotiable.
Step 2: Note Your Current Version
Check your current n8n version:
docker compose exec n8n n8n --version
1.123.5
Save this somewhere — you need to know your starting point for rollback.
You can also see the version in the n8n UI: click the settings icon in the left sidebar, and the version appears at the bottom.
Step 3: Check the Changelog
Before updating, review what changed:
- Go to n8n GitHub Releases
- Find versions between your current version and the target version
- Look for "Breaking Changes" sections — these might affect existing workflows
- Check for database migrations (these happen automatically, but good to know)
If you see breaking changes that affect your workflows, plan accordingly — maybe update on a weekend when you can monitor.
Version Management: :latest vs Pinned
Open your docker-compose.yml:
nano /opt/n8n/docker-compose.yml
The Problem with :latest
If your image line looks like this:
image: n8nio/n8n
Or this:
image: n8nio/n8n:latest
Every time you run docker compose pull, you get whatever is newest. This is:
- Simple
- But dangerous — updates can surprise you with breaking changes
The Solution: Pin Your Version
Instead, specify an exact version:
image: docker.n8n.io/n8nio/n8n:2.0.2
With a pinned version:
- You decide when to update
- You have complete control
- Rollback is trivial
Best practice:
- Production: Always pin your version. Update deliberately, not accidentally.
- Development/Testing:
:latestis fine.
Pro tip: Pick a version that's been out for at least a few days. Let others find the bugs first. Check Docker Hub tags sorted by newest.
Live Update Demo
Let's update n8n step by step.
1. Backup First
/opt/n8n/backup.sh
2. Update the Version in docker-compose.yml
nano /opt/n8n/docker-compose.yml
Change the image line to your target version:
image: docker.n8n.io/n8nio/n8n:2.0.2
Save and exit.
3. Pull the New Image
docker compose pull
[+] Pulling 1/1
✔ n8n Pulled
This downloads the new version but doesn't restart anything yet. Your n8n is still running the old version.
4. Restart with New Version
docker compose up -d
[+] Running 1/1
✔ Container n8n Started
This stops the old container and starts a new one with the updated image.
5. Verify the Update
docker compose exec n8n n8n --version
2.0.2
Open n8n in your browser and verify:
- Version shows correctly in settings
- Your workflows are still there
- Everything works as expected
Total downtime: ~30 seconds.
Rollback Demo
What if the update breaks something? Here's how to rollback.
If You Used :latest
Bad news — if you were using :latest and just pulled, you can't easily go back. The old image is gone.
This is why I recommend pinned versions.
If You Used Pinned Versions
Rollback is simple:
1. Edit docker-compose.yml:
nano /opt/n8n/docker-compose.yml
2. Change the version back:
image: docker.n8n.io/n8nio/n8n:1.123.5
3. Pull and restart:
docker compose pull
docker compose up -d
4. Verify:
docker compose exec n8n n8n --version
1.123.5
Key point: Your workflows, credentials, everything is still there. The data lives in the volume, not the container. Changing versions doesn't touch your data.
Nuclear Option: Full Restore from Backup
If something went deeply wrong — database migration corrupted data, or you accidentally deleted the volume — here's the nuclear option.
1. Stop n8n
docker compose down
2. Delete the Volume
docker volume rm n8n_n8n_data
Warning: This deletes all your data. Only do this if you have a backup!
3. Recreate the Volume
docker volume create n8n_n8n_data
4. List Your Backups
ls /opt/n8n/backups/
n8n-backup-20251216-140522.tar.gz
n8n-backup-20251216-143022.tar.gz
5. Restore from Backup
Pick the backup you want (usually the most recent before the failed update):
docker run --rm \
-v n8n_n8n_data:/target \
-v /opt/n8n/backups:/backup \
alpine sh -c "cd /target && tar xzf /backup/n8n-backup-20251216-143022.tar.gz"
Replace the filename with your actual backup file.
6. Start n8n
docker compose up -d
Wait a moment for n8n to initialize (database migrations may run), then verify everything is restored.
This is your full restore — back to exactly where you were before the failed update.
Quick Reference: Safe Update Workflow
| Step | Command | Purpose |
|---|---|---|
| 1. Backup | /opt/n8n/backup.sh | Safety net |
| 2. Note version | docker compose exec n8n n8n --version | Know your starting point |
| 3. Check changelog | GitHub Releases | Look for breaking changes |
| 4. Pin version | Edit docker-compose.yml | Control when updates happen |
| 5. Pull | docker compose pull | Download new image |
| 6. Restart | docker compose up -d | Apply update |
| 7. Verify | Check version + test workflows | Confirm success |
Rollback Cheatsheet
Quick rollback (pinned version):
# Edit docker-compose.yml to previous version, then:
docker compose pull
docker compose up -d
Full restore (nuclear option):
docker compose down
docker volume rm n8n_n8n_data
docker volume create n8n_n8n_data
docker run --rm -v n8n_n8n_data:/target -v /opt/n8n/backups:/backup alpine sh -c "cd /target && tar xzf /backup/YOUR-BACKUP-FILE.tar.gz"
docker compose up -d
What's Next
In Part 5, I'll show you how to get notified on your phone the moment any workflow fails — before your clients even know something is wrong.
n8n Series:
- Part 1: Local Setup
- Part 2: Deploy to Production
- Part 3: Backups & Recovery
- Part 4: Updates & Rollbacks (This post)
- Part 5: Monitoring & Alerts (Coming soon)
Resources
Questions? Drop a comment on the video — I read and reply to all of them.