Skip to content

Upgrade the embedded PostgreSQL database (15 → 18)

This runbook only applies to the all-in-one image running its embedded PostgreSQL database — that is, you did not pass DATABASE_HOST / POSTGRESQL_* environment variables when starting the container. If you run an external PostgreSQL server, nothing here applies: upgrade that server on its own schedule. Saveroom supports PostgreSQL >= 14.

The all-in-one image's base moved to Ubuntu 26.04 LTS, which ships PostgreSQL 18. A PostgreSQL data directory initialised by version 15 cannot be read by version 18, so the container refuses to start rather than risk your data:

Your PostgreSQL data directory was initialized with version 15, but this image is
running version 18.

The upgrade path is a logical dump with the old image and a restore into a fresh data volume with the new one.

Before you start

  • Take a full backup first, following Back-up Saveroom. The steps below create a new volume and leave the old one untouched, but a separate backup is still the safety net if something goes wrong halfway.
  • Note the exact image tag you are currently running (docker inspect baserow) — you need it to start the old PostgreSQL 15 cluster one last time.
  • Budget downtime proportional to your database size; the dump and restore are both single-threaded.

Below, OLD_TAG is the version you run today (PostgreSQL 15) and NEW_TAG is the version you are upgrading to (PostgreSQL 18).

1. Stop Saveroom

docker stop baserow

Confirm nothing else is still attached to the data volume with docker ps.

2. Dump the database with the old image

The old image still contains the PostgreSQL 15 server, so it can start the existing cluster and dump it. Write the dump to your host, outside both volumes:

docker run -it --rm \
  -v baserow_data:/baserow/data \
  -v "$PWD":/baserow/host \
  ghcr.io/carneirofc/baserow:OLD_TAG \
  backend-cmd-with-db backup -f /baserow/host/pg15-backup.tar.gz

Check that pg15-backup.tar.gz exists in the current directory and is not zero-length before continuing.

3. Create a fresh data volume

Do not delete the old volume. Keep it until the upgrade is verified — it is your rollback.

docker volume create baserow_data_pg18

4. Restore into the new image

The new image initialises an empty PostgreSQL 18 cluster in the new volume and restores the dump into it:

docker run -it --rm \
  -v baserow_data_pg18:/baserow/data \
  -v "$PWD":/baserow/host \
  ghcr.io/carneirofc/baserow:NEW_TAG \
  backend-cmd-with-db restore -f /baserow/host/pg15-backup.tar.gz

5. Start Saveroom on the new volume

Use your normal run command, with the volume swapped:

docker run -d \
  --name baserow \
  -v baserow_data_pg18:/baserow/data \
  # ... the rest of your usual arguments
  ghcr.io/carneirofc/baserow:NEW_TAG

Watch the startup logs (docker logs -f baserow). The PostgreSQL version guard should no longer fire, and migrations should run to completion.

6. Verify, then clean up

Log in and confirm your workspaces, tables and row counts look right. Only once you are satisfied:

docker volume rm baserow_data          # the old PostgreSQL 15 volume
rm pg15-backup.tar.gz

Rollback

If anything goes wrong, the old volume is unchanged. Start your previous image tag against it again:

docker run -d --name baserow -v baserow_data:/baserow/data \
  # ... the rest of your usual arguments
  ghcr.io/carneirofc/baserow:OLD_TAG

Then open an issue at https://github.com/carneirofc/baserow/issues with the container logs from the failed attempt.