Skip to content

Upgrading Tenants

Guide to upgrading tenant instances to new cbapp versions.

Overview

The upgrade process:

  1. Stop services
  2. Backup database
  3. Git checkout new version
  4. Install dependencies
  5. Run migrations
  6. Start services
  7. Health check

Check Available Upgrades

# Check current version vs latest
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:32201/api/tenants/{tenant_id}/version

# Response:
{
  "deployed_version": "v0.2.0",
  "deployed_commit": "295fb7f",
  "latest_version": "v0.3.0",
  "latest_commit": "17b3ab3",
  "upgrade_available": true
}

Perform Upgrade

Via API

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "target_version": "v0.3.0",
    "backup_db": true,
    "run_migrations": true
  }' \
  http://localhost:32201/api/tenants/{tenant_id}/upgrade

Parameters

Parameter Default Description
target_version latest tag Version to upgrade to (e.g., "v0.3.0")
backup_db true Create database backup before upgrade
run_migrations true Run migration scripts after checkout

Response

{
  "status": "success",
  "previous_version": "v0.2.0",
  "new_version": "v0.3.0",
  "commit": "17b3ab3",
  "migrations_run": [
    "scripts/create_schema.py",
    "scripts/create_default_users.py",
    "scripts/add_person_columns.py"
  ],
  "backup_path": "/path/to/pocket.db.backup_20251211_225756",
  "details": [
    "Stopping services...",
    "Services stopped",
    "Backing up database...",
    "Database backed up",
    "Fetching latest code...",
    "Checking out v0.3.0...",
    "Installing dependencies...",
    "Dependencies installed",
    "Running migrations...",
    "Ran 6 migrations",
    "Starting services...",
    "Services started",
    "Health check passed"
  ]
}

Batch Upgrades

Upgrade multiple tenants:

# Get all tenant IDs
TENANTS=$(curl -s -H "Authorization: Bearer $TOKEN" \
  http://localhost:32201/api/tenants | jq -r '.tenants[].id')

# Upgrade each
for ID in $TENANTS; do
  echo "Upgrading $ID..."
  curl -X POST -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"target_version": "v0.3.0", "backup_db": true}' \
    http://localhost:32201/api/tenants/$ID/upgrade
done

Rollback

If an upgrade fails, restore from backup:

# Stop services
sudo systemctl stop {slug}-api {slug}-frontend

# Restore database
cp /path/to/pocket.db.backup_TIMESTAMP /path/to/{slug}/db/pocket.db

# Checkout previous version
cd /path/to/{slug}
git checkout v0.2.0

# Start services
sudo systemctl start {slug}-api {slug}-frontend

Migration Scripts

Migrations are idempotent - they check before executing:

# Example from add_person_columns.py
if col_name in existing_columns:
    print(f"  ✓ {col_name} (already exists)")
    skipped += 1
else:
    conn.execute(f"ALTER TABLE person ADD COLUMN {col_name} {col_type}")
    added += 1

Current migrations:

Script Description
create_schema.py Core tables
create_default_users.py Admin user
add_person_columns.py Extended contact fields
migrate_add_import_metadata.py Import tracking columns
add_person_indexes.py Performance indexes
add_segment_tables.py Segment management

Best Practices

  1. Always backup: Use backup_db: true
  2. Test first: Upgrade testsite before production
  3. Check health: Verify services after upgrade
  4. Monitor logs: Watch for errors during upgrade

Troubleshooting

Upgrade Fails at Git Fetch

# Fix remote tracking
cd /path/to/{slug}
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"

Services Don't Start After Upgrade

# Check logs
sudo journalctl -u {slug}-api -f

# Common issues:
# - New dependency not installed
# - Database migration failed
# - Port conflict

See Also