Skip to main content

Upgrading & Pinning n8n

n8n ships inside the compose stack, so you upgrade it independently of the Circus API and frontend — a version bump touches only the n8n container. The one recommendation to internalise: pin a specific version rather than riding an implicit latest, so upgrades are deliberate.

Check what's running

cd /app/staging
VERSION=staging-latest docker compose -p staging --env-file .env -f deploy/docker-compose.prod.yml exec n8n n8n --version

Pin or upgrade

Edit deploy/docker-compose.prod.yml and give the n8n image an explicit tag:

image: n8nio/n8n → image: n8nio/n8n:1.52.0

Then pull and restart only n8n — the API, frontend, and Postgres are untouched:

VERSION=staging-latest docker compose -p staging --env-file .env -f deploy/docker-compose.prod.yml pull n8n
VERSION=staging-latest docker compose -p staging --env-file .env -f deploy/docker-compose.prod.yml up -d n8n

Verify with ... ps n8n and ... logs n8n --tail 20. (Swap -p staging / VERSION=staging-latest for the production equivalents when upgrading production.)

Why pin

An unpinned latest means an unrelated pull — or a rebuild — can silently move n8n to a new major version, and n8n's node behaviour and env-var handling do change across versions. Pinning makes every n8n upgrade an explicit, reviewable edit to the compose file, which is exactly what you want for the component that runs your workflows. Test an n8n upgrade on staging before applying it to production.