Upgrades and migrations
Order matters. Read this before pulling.
The rule
Apply database migrations before starting the new containers.
New code expects the new schema. Started the other way round, the new containers fail against the old schema — and the failure is noisy but not obvious. The reverse order is safe: the old code keeps working fine after the schema has moved forward.
Upgrading
# 1. Back up first. Always.
docker compose exec -T postgres pg_dump -U lenshub lenshub | gzip > backup.sql.gz
# 2. Pull the new images
docker compose pull
# 3. Apply migrations
./services/postgres/migrate.sh --apply
# 4. Start the new containers
docker compose up -dChecking what will happen
./services/postgres/migrate.sh --statusLists every migration as applied or pending, without changing anything.
Migrations are additive
They add tables, columns and indexes; they do not drop your data. That makes them safe to apply while the old version is still running, which is what allows the ordering above.
Some build indexes concurrently, which takes minutes on a large database but does not block reads or writes.
After upgrading
docker compose ps # everything healthy
curl http://localhost:8080/readyz # {"status":"ok"}Then confirm a search still returns results — schema and code agreeing is necessary but not sufficient.
Rolling back
Migrations are additive, so the previous version generally runs against the newer schema without complaint. Restore from a backup if it does not.
Upgrade a staging instance first if you have one. If you do not, take the backup in step 1 seriously — it is the whole rollback plan.