Upgrade Procedure

📦v1.0.0📅2026-04-28🔄Updated 2026-04-28👤Admin Team
administrationdeploymentupgrade

Upgrade Procedure

This page covers the recommended sequence for upgrading a running Message Center instance to a new version.


Before You Start

Complete this checklist before every upgrade:

  • Read the release notes for the new version — look for breaking changes, new required env vars, and migration notes
  • Take a MongoDB backup (see Backups & Recovery)
  • Verify the backup is restorable (spot-check one collection)
  • Confirm the audit fallback file is empty (GET /api/diagnostics/auditfallbackFileSize: 0)
  • Note the current schema version (Diagnostics page → DB schema tile or db.meta.findOne())
  • Schedule the upgrade during a low-traffic window if possible

Upgrade Sequence

The critical rule: migrations must run before new pods start. This ensures the new code never reads a schema it doesn't understand and the old code never writes to a schema it hasn't seen yet.

Kubernetes

# 1. Drain active requests (optional — rolling update handles this, but
#    explicit drain reduces mid-upgrade errors for long-running requests)
kubectl rollout pause deployment/core-admin

# 2. Run migrations with the NEW image
kubectl run -it --rm migrate \
  --image=<your-registry>/core-admin:<new-tag> \
  --restart=Never \
  -- yarn migrate

# 3. Verify migrations completed — should show schema_version: <expected>
kubectl run -it --rm check-version \
  --image=<your-registry>/core-admin:<new-tag> \
  --restart=Never \
  -- node -e "
    require('dotenv/config');
    const {getDb} = require('./src/lib/db/mongo');
    getDb().then(db => db.collection('meta').findOne({_id:'schema'}))
      .then(d => { console.log('schema_version:', d?.schema_version); process.exit(0); })
  "

# 4. Update the deployment image
kubectl set image deployment/core-admin \
  core-admin=<your-registry>/core-admin:<new-tag>

# 5. Resume the rollout
kubectl rollout resume deployment/core-admin

# 6. Watch rollout progress
kubectl rollout status deployment/core-admin --timeout=5m

Docker Compose (production)

# 1. Pull the new image
docker pull <your-registry>/core-admin:<new-tag>

# 2. Run migrations with the new image
docker run --env-file .env <your-registry>/core-admin:<new-tag> yarn migrate

# 3. Restart the stack with the new image
IMAGE_TAG=<new-tag> make prod-up   # or docker compose up -d

Development

git pull
yarn install --frozen-lockfile
make migrate
make dev

Post-Upgrade Validation

After the new pods are running:

  1. Open the Diagnostics page and verify:

    • Core API shows OK
    • DB schema shows the expected new version number
    • Audit fallback shows file empty ✓
  2. Create a test campaign (if possible in a staging environment) to verify the moderation flow is intact.

  3. Check application logs for errors in the first few minutes:

    kubectl logs -l app=core-admin --since=5m
    
  4. If you see MongoServerError or TypeError referencing unknown fields, migrations may not have completed. Run make migrate again.


Rollback Procedure

If the upgrade must be reverted:

# 1. Roll back the deployment to the previous image
kubectl rollout undo deployment/core-admin

# 2. Verify rollback completed
kubectl rollout status deployment/core-admin

# 3. If migrations ran (schema changed), restore from the pre-upgrade backup
mongorestore \
  --uri="$MONGODB_URI" \
  --db="$MONGODB_DB" \
  --archive=/backups/pre-upgrade.gz \
  --gzip \
  --drop

Migrations are one-way. If the new version added migrations that the old code doesn't understand, you must restore from backup — rolling back the image without restoring the database will cause schema mismatch errors.


Handling New Environment Variables

When a new release introduces required environment variables:

  1. Add them to the Kubernetes Secret or ConfigMap before running migrations or deploying.
  2. Missing required variables cause the application to exit at startup with a clear error.
  3. New optional variables with safe defaults (shown in .env.example) do not require action unless you want to change the default behavior.

Check .env.example in the new release tag for a full list of variables and their defaults.


Next Steps