Before you upgrade
- Read the changelog for every version between yours and the target, not just the target.
- Take a database backup and confirm it exists:bash
./scripts/backup-db.sh ls -la backups/ - Note your current version, so you know what to roll back to.
Shellius runs migrations automatically on API boot. That is convenient, and it means an upgrade starts changing your schema the moment the new container starts. Take the backup first.
The standard upgrade
cd /opt/shellius
git fetch --tags
git checkout v1.5.3
docker compose -f docker-compose.prod.yml --env-file .env.prod pull
docker compose -f docker-compose.prod.yml --env-file .env.prod up -d
docker compose -f docker-compose.prod.yml ps
docker compose -f docker-compose.prod.yml logs backend --tail=50Migrations run as the API starts. Watch the logs until it reports healthy.
Check .env.prod.example for variables added since your version:
diff <(grep -o '^[A-Z_]*' .env.prod.example | sort -u) \
<(grep -o '^[A-Z_]*' .env.prod | sort -u)Verify
Do not call it done because the containers are healthy:
- Sign in to the portal.
- Confirm the CA public key under Administration → Certificate authority is unchanged. If it changed, stop — every host now distrusts you.
- Request access to a non-production host and connect. This exercises signing,
check-principals, and the API path together. - Check the audit log is still recording.
Rolling back
Roll back the code and images:
git checkout v1.5.2
docker compose -f docker-compose.prod.yml --env-file .env.prod up -dWARNING
This does not roll back the database. If the newer version applied a migration that the older one cannot read, the old version will fail to start, and you have to restore the database backup you took before upgrading. This is why the backup is not optional.
The YavLabs deploy script
scripts/update-shellius.sh automates clone, image tagging, backup, migrate, swap, and health check — including a --rollback. It is written for the YavLabs deployment topology (docker-compose.deploy.yml, an external PostgreSQL behind PgBouncer) and its defaults point at that infrastructure.
If your deployment looks different, use the standard upgrade above, or read the script and override APP_DIR, PG_HOST, DIRECT_DATABASE_URL, and HEALTH_URL for your own environment.