Upgrading PostgreSQL¶
PostgreSQL major version upgrades (e.g., 15 → 16) require a database migration. The internal storage format changes between major versions, so you cannot simply change the image tag.
Note: Minor version upgrades (e.g., 16.4 → 16.8) are safe and only require changing the image tag and restarting the container.
Prerequisites¶
- Familiarity with the command line and Docker
- Access to your
docker-compose.ymlfile and data directories - Sufficient disk space for the database backup (at least 2x your current database size)
Step-by-Step Upgrade Guide¶
1. Stop the Readur application container¶
Prevent new data writes during the migration:
2. Create a full backup¶
This is a critical safety step. Create a SQL dump of your PostgreSQL database:
# Find your PostgreSQL container name
docker ps --format "{{.Names}}" | grep postgres
# Create a SQL dump (replace 'readur-postgres' with your container name)
docker exec -t readur-postgres pg_dumpall -U readur > readur_backup.sql
# Verify the dump file exists and has content
ls -lh readur_backup.sql
head -50 readur_backup.sql # Preview the dump to ensure it's valid
3. Stop the PostgreSQL container¶
4. Back up the current database data directory¶
This provides an additional safety net:
# If using named volume (recommended)
docker volume create postgres_data_backup
docker run --rm -v postgres_data:/source -v postgres_data_backup:/backup alpine cp -a /source/. /backup/
# If using host path (e.g., ./postgres or /volume1/docker/readur/postgres)
mv ./postgres ./postgres_old_backup
5. Update docker-compose.yml¶
Change the PostgreSQL version to your target version:
6. Remove the old data volume¶
The new PostgreSQL version needs a fresh data directory:
# If using named volume
docker volume rm postgres_data
# If using host path, it was already moved in step 4
7. Start the new PostgreSQL container¶
Docker will create a new, empty data directory:
8. Import the database dump¶
Restore your data into the new PostgreSQL instance:
Note: If you get "the input device is not a TTY" error, use
-Tinstead of-i:
9. Start Readur¶
10. Verify the upgrade¶
- Check logs for errors:
docker compose logs -f readur - Confirm all documents are accessible in the web UI
- Test search functionality
- Verify OCR processing works on a test document
11. Clean up¶
Only after confirming everything works properly:
# Remove old data backup
rm -rf ./postgres_old_backup
# Or for named volumes:
docker volume rm postgres_data_backup
# Remove dump file
rm readur_backup.sql
Troubleshooting¶
| Error | Solution |
|---|---|
FATAL: database files are incompatible with server | You tried to use old data with new postgres. Remove the data volume and follow the migration steps above. |
role "readur" does not exist | The dump didn't restore properly. Re-run step 8. |
could not connect to server | Wait for postgres healthcheck to pass. Check docker compose logs postgres. |
permission denied | Ensure the postgres container has write access to the data directory. Use named volumes. |
Alternative Methods¶
Using pg_upgrade (Advanced)¶
For large databases where dump/restore takes too long, you can use tianon/docker-postgres-upgrade:
docker run --rm \
-v postgres_data_old:/var/lib/postgresql/15/data \
-v postgres_data_new:/var/lib/postgresql/16/data \
tianon/postgres-upgrade:15-to-16 --link
This is faster but more complex. See the project documentation for details.
Using pgautoupgrade (Automatic)¶
The pgautoupgrade/docker-pgautoupgrade image automatically detects and upgrades your database:
Warning: This performs in-place upgrades. Always have backups before using this approach.