--- title: "How to Update n8n to the Latest Version with Docker Compose" description: "Update a self-hosted n8n instance running on Docker Compose: back up the database and data volume, pull the new image, verify the version and roll back safely." category: "Apps" language: en source: https://cubepath.com/docs/apps/how-to-update-n8n-to-latest-version updated: 2026-09-25 --- # How to Update n8n to the Latest Version with Docker Compose n8n ships new releases frequently, with security fixes, new nodes and bug fixes. When you self-host it with Docker Compose, updating means pulling a newer image and recreating the container, but a careless update can break workflows or run database migrations you cannot undo. In this tutorial you will back up your n8n instance, update it to the latest version, verify that it works, and learn how to roll back if something goes wrong. ## Prerequisites To follow this guide you need: - A server running n8n with Docker Compose, for example on an [n8n VPS](/vps/vps-n8n) from CubePath with Ubuntu 24.04. This guide assumes the project lives in `/opt/n8n` and uses PostgreSQL; adjust the path and service names to your setup. - A non-root user with `sudo` privileges, or a user in the `docker` group. - Docker Engine with the Compose plugin (`docker compose`, not the legacy `docker-compose` binary). - Enough free disk space for a database dump and a second copy of the n8n image (about 2 GB). ## Step 1 - Checking the current version and reading the release notes Go to the directory that contains your `docker-compose.yml` (or `compose.yaml`): ```bash cd /opt/n8n ``` List the services so you know their names. The rest of this guide assumes they are called `n8n` and `postgres`: ```bash docker compose ps ``` ```output NAME IMAGE SERVICE STATUS PORTS n8n-n8n-1 docker.n8n.io/n8nio/n8n n8n Up 3 weeks 0.0.0.0:5678->5678/tcp n8n-postgres-1 postgres:16 postgres Up 3 weeks 5432/tcp ``` Check which n8n version you are running: ```bash docker compose exec n8n n8n --version ``` ```output 2.1.4 ``` Before updating, read the release notes on the n8n GitHub releases page and the "Breaking changes" section of the n8n documentation for every version between yours and the latest one. Minor releases are usually safe; a major version jump can remove deprecated features or change behavior, and n8n publishes a migration guide for it. Also check which tag your Compose file uses: ```bash grep -n "image:" docker-compose.yml ``` ```output 3: image: docker.n8n.io/n8nio/n8n 12: image: postgres:16 ``` An image without a tag (or with `:latest`) follows the latest stable release. If the file pins a version such as `docker.n8n.io/n8nio/n8n:2.1.4`, edit it with `nano docker-compose.yml` and set the version you want to move to. ## Step 2 - Backing up the database and the data volume n8n stores workflows, credentials and execution history in the database, and keeps its encryption key in `/home/node/.n8n` inside the container. You need both to restore an instance, because credentials cannot be decrypted without that key. Create a backup directory: ```bash sudo mkdir -p /opt/n8n-backups ``` Dump the PostgreSQL database. Replace `n8n` with the `POSTGRES_USER` and `POSTGRES_DB` values from your `.env` or Compose file: ```bash docker compose exec -T postgres pg_dump -U n8n -d n8n -Fc | sudo tee /opt/n8n-backups/n8n-$(date +%F).dump > /dev/null ``` Find the name of the volume mounted at `/home/node/.n8n`. Compose prefixes volume names with the project name: ```bash docker volume ls ``` ```output DRIVER VOLUME NAME local n8n_n8n_data local n8n_db_storage ``` Archive the n8n data volume with a temporary container: ```bash docker run --rm -v n8n_n8n_data:/data:ro -v /opt/n8n-backups:/backup alpine tar czf /backup/n8n_data-$(date +%F).tar.gz -C /data . ``` Check that both files exist and are not empty: ```bash ls -lh /opt/n8n-backups ``` ```output -rw-r--r-- 1 root root 48M Sep 25 10:12 n8n-2026-09-25.dump -rw-r--r-- 1 root root 1.2M Sep 25 10:13 n8n_data-2026-09-25.tar.gz ``` > Note: If your instance uses the default SQLite database instead of PostgreSQL, the database file (`database.sqlite`) lives inside the data volume, so the volume archive is your full backup. Stop n8n with `docker compose stop n8n` before archiving so the file is consistent. ## Step 3 - Pulling the new image Download the new image while the current version keeps running. This keeps downtime to the few seconds it takes to recreate the container: ```bash docker compose pull n8n ``` ```output [+] Pulling 1/1 n8n Pulled ``` ## Step 4 - Recreating the container Apply the update. Compose only recreates the containers whose image or configuration changed, so PostgreSQL keeps running: ```bash docker compose up -d ``` ```output [+] Running 2/2 Container n8n-postgres-1 Running Container n8n-n8n-1 Started ``` There is no need to run `docker compose down` first. `down` removes the containers and the network, which adds downtime and gives you nothing extra here. ## Step 5 - Verifying the update Follow the n8n logs while it starts. On a version jump, n8n runs its database migrations at this point: ```bash docker compose logs -f n8n ``` Wait until you see a line like this, then press `CTRL+C`: ```output Editor is now accessible via: http://localhost:5678 ``` Confirm the new version: ```bash docker compose exec n8n n8n --version ``` ```output 2.4.0 ``` Check the health endpoint from the server: ```bash curl -s http://localhost:5678/healthz ``` ```output {"status":"ok"} ``` Finally, log in to the editor, open a couple of important workflows and run them manually, and check that credentials still connect. ## Step 6 - Cleaning up old images Each update leaves the previous image on disk. Once you are happy with the new version, remove unused images: ```bash docker image prune ``` Keep the backups from Step 2 for at least a few days before deleting them. ## Rolling back to the previous version If the new version breaks something, pin the old version in `docker-compose.yml`, for example: ```yaml image: docker.n8n.io/n8nio/n8n:2.1.4 ``` Database migrations are not always reversible, so restore the database dump before starting the old version. Stop n8n, restore the dump, and start again: ```bash docker compose stop n8n docker compose exec -T postgres pg_restore -U n8n -d n8n --clean --if-exists < /opt/n8n-backups/n8n-2026-09-25.dump docker compose up -d ``` Verify the version with `docker compose exec n8n n8n --version` as in Step 5. ## Updating an npm installation If you installed n8n with npm instead of Docker, back up `~/.n8n` and your database, then install the latest release globally and restart the service that runs it: ```bash sudo npm install -g n8n@latest n8n --version ``` ## Troubleshooting - **`docker-compose: command not found`.** The legacy v1 binary is no longer maintained. Use `docker compose` (with a space), provided by the `docker-compose-plugin` package from Docker's repository. - **Credentials fail with "could not be decrypted".** The container started with a different encryption key. Make sure the data volume is mounted at `/home/node/.n8n`, or that `N8N_ENCRYPTION_KEY` in your environment has the same value as before. - **The container restarts in a loop after the update.** Read `docker compose logs n8n`. Migration errors usually point to a skipped major version or an unsupported database version: roll back and follow the migration guide for that release. ## Conclusion You backed up your n8n database and encryption key, updated n8n to the latest image with only a few seconds of downtime, and verified the result with the version command and the health endpoint. To keep this routine safe, schedule regular database dumps with cron or a systemd timer, and consider pinning explicit version tags so updates only happen when you decide.