
Yesterday I upgraded my instance of paperless-ngx. However, even after reading the changelogs intensively, I had not read the issue that was coming up. The “webserver” container is not starting anymore. The reason: postgres was not coming up.
Regarding the setup: I use a docker-compose file to start my paperless-ngx instance and its db+redis.
The error message in the postgres 18 container was:
Error: in 18+, these Docker images are configured to store database data in a format which is compatible with "pg_ctlcluster" (specifically, using major-version-specific directory names). This better reflects how PostgreSQL itself works, and how upgrades are to be performed.
See also https://github.com/docker-library/postgres/pull/1259
Counter to that, there appears to be PostgreSQL data in: /var/lib/postgresql/data
This is usually the result of upgrading the Docker image without upgrading the underlying database using "pg_upgrade" (which requires both versions).
The suggested container configuration for 18+ is to place a single mount at /var/lib/postgresql which will then place PostgreSQL data in a subdirectory, allowing usage of "pg_upgrade --link" without mount point boundary issues.
See https://github.com/docker-library/postgres/issues/37 for a (long) discussion around this process, and suggestions for how to do so.
Ok, now let’s fix it!
The Issue: Version-Specific Directories
Starting with PostgreSQL 18, the official Docker images changed their internal storage format. Instead of storing everything directly in the /data folder, they now use version-specific subdirectories (like /16/data or /18/data). This is designed to make future upgrades easier, but it breaks existing setups that mount directly to the old /data path.
The Solution: pgautoupgrade
Instead of the tedious “dump, wipe, and restore” method, there is a specialized tool that handles the migration and the directory restructuring automatically.
Step 0: BACKUP
Create a backup the way you always do. At least do a “cp -r pgdata pgdata_BACKUP”.
Step 1: Run the Migration Tool
First, stop your Paperless-ngx stack. Then, run this “one-shot” container (ensure your paths and environment variables match your setup):
docker run --rm \
-v /home/dockeruser/docker-mounts/paperless-ngx/pgdata:/var/lib/postgresql \
-e POSTGRES_USER=paperless_user22 \
-e POSTGRES_PASSWORD=pw123 \
-e POSTGRES_DB=paperless \
-e PGAUTO_ONESHOT=yes \
pgautoupgrade/pgautoupgrade:18-trixie
Step 2: Update your docker-compose.yml
Once the tool finishes, you must adjust your db service volume mapping (you can also do it beforehand as well). The container now expects to be mounted at the parent level:
- Before:
/.../pgdata:/var/lib/postgresql/data - After:
/.../pgdata:/var/lib/postgresql
By removing the /data suffix from the container side of the mount, you allow PostgreSQL to manage its new versioned subfolders correctly. Restart your stack with docker-compose up -d, and you’re good to go!
This solved my problem and was very fast and reliable.
A related issue on git of paperless-ngx is:
https://github.com/docker-library/postgres/issues/37
0 Comments