Skip to content

Upgrading

club follows semantic versioning. Pending database migrations are applied automatically on every startup, so upgrading is typically as simple as pulling a new image and restarting: there are no manual migration commands.

Before You Upgrade

  1. Read the release notes for the version you are upgrading to. Check for breaking changes or special migration instructions.

  2. Back up your data. See Backup & Restore for instructions. At minimum, back up the metadata store (database).

  3. Test in a staging environment if possible, especially for major version upgrades.


Upgrade Steps

  1. Back up your data:

    Terminal window
    # SQLite
    sqlite3 /data/db/club.db ".backup /backups/club-pre-upgrade.db"
    # Filesystem blobs (tarballs + screenshots + blob-mode dartdoc)
    tar -czf /backups/blobs-pre-upgrade.tar.gz -C /data blobs/
  2. Pull the new image:

    Terminal window
    docker pull club:latest
    # Or pin to a specific version:
    docker pull club:1.2.0
  3. Stop the current container:

    Terminal window
    docker compose down
  4. Start with the new image:

    Terminal window
    docker compose up -d
  5. Verify the upgrade:

    Terminal window
    # Check health
    curl https://packages.example.com/api/v1/health
    # Check version in response
    curl -s https://packages.example.com/api/v1/health | jq .version
    # Tail logs for any errors during schema application
    docker compose logs club --tail 50

If using a specific version tag in your docker-compose.yml, update it:

services:
club:
image: club:1.2.0 # Update version here

Schema Behavior

Versioned Migrations

club tracks the SQLite schema version in a club_schema metadata table and applies a gap-free chain of numbered migrations on startup:

  • A fresh database has the canonical schema applied (CREATE TABLE, CREATE VIRTUAL TABLE ... USING fts5(...), etc.) and is then stamped directly at the current schema version.
  • An existing database is read for its stamped version and stepped forward through each pending SchemaMigration (typically ALTER TABLE ... ADD COLUMN statements) until it reaches the current version.

The whole operation runs inside a single BEGIN IMMEDIATE transaction, so a crash or statement failure rolls the database back to its previous version cleanly, and two replicas starting concurrently can’t race the same step.

What This Means for Upgrades

ScenarioBehavior
Fresh installCanonical schema applied, then stamped at the current version
Existing database behind by one or more versionsPending migrations applied in order on first boot of the new binary
New columns added in a new versionAdded via an ALTER TABLE migration step
Column renames or dropsShipped as explicit migration statements — see release notes
Unchanged schema (already at current version)No-op; nothing runs

You do not run a “migrate” command before or after upgrading. The server applies pending migrations during boot, before it starts accepting requests.


Rollback Procedure

If an upgrade causes issues, you can roll back to the previous version.

  1. Stop the server:

    Terminal window
    docker compose down
    # or: systemctl stop club
  2. Restore the database from backup:

    Terminal window
    # SQLite
    cp /backups/club-pre-upgrade.db /data/db/club.db
    # PostgreSQL
    pg_restore -h db.example.com -U club -d club /backups/club-pre-upgrade.dump
  3. Restore blob storage if needed:

    Terminal window
    tar -xzf /backups/packages-pre-upgrade.tar.gz -C /data
  4. Switch back to the previous version:

    Terminal window
    # Docker
    # Edit docker-compose.yml to use the previous image tag
    docker compose up -d
    # From source
    git checkout v1.1.0
    dart build cli -t packages/club_server/bin/server.dart -o build/server
    sudo cp build/server/bundle/bin/server /usr/local/bin/club
    systemctl start club
  5. Verify the rollback:

    Terminal window
    curl https://packages.example.com/api/v1/health

Any packages published or tokens created after the upgrade are lost with the database restore. This is why backing up before upgrading is critical.


Version Pinning

For production deployments, always pin to a specific version rather than using latest:

docker-compose.yml
services:
club:
image: club:1.2.0 # Pin to specific version

This prevents accidental upgrades and ensures reproducible deployments. Update the version tag deliberately after testing.