Upgrades and Migrations
Upgrade Model
Section titled “Upgrade Model”Treat three things separately:
- Binary or image version: controls code behavior and APIs.
- Database migrations: control schema and may be irreversible.
- Configuration and deployment templates: control network surfaces, secrets, dependencies, cache, cluster, and observability.
Release Preflight
Section titled “Release Preflight”- Read release notes or change logs for the target version.
- Back up PostgreSQL and production secrets.
- If the secret management model changes, first use Security Hardening and Rotation to decide whether direct rotation is safe.
- Restore production-like data into a test environment, start the target version, and verify automatic migrations and business reads/writes.
- Run
synctv config validate --strict. - Save
synctv config show --output yamlas the current effective config snapshot. - Compare against the Configuration Index and Full Configuration Example.
- If protocol or protobuf behavior changes, confirm API and Protobuf Evolution and client examples are updated.
- For Helm, run
helm lintandhelm template. - For Compose, run
docker compose config.
Database Migration
Section titled “Database Migration”SyncTV runs embedded SQLx migrations automatically during service startup. Migration state is stored in _sqlx_migrations, and SQLx uses database-side locking so the same migration set is not executed concurrently by multiple replicas. Multi-replica startup does not require a Job to manually serialize migrations, and administrators do not need to decide whether an upgrade needs migrations.
synctv db migrate remains available as an explicit operations command for release preflight, CI, test environments, and troubleshooting. It runs the same embedded migrations that service startup runs automatically.
Check status:
synctv db statusOptional preflight:
synctv db migrateCompose example:
docker compose run --rm synctv synctv db migrateRunning synctv db migrate separately in production is a release-process choice, not a correctness requirement. Its value is observability and failure isolation: it can surface dirty migrations, checksum drift, or database privilege issues before the new version receives traffic. If it is not run separately, service startup still applies pending migrations automatically.
Docker Compose Upgrade
Section titled “Docker Compose Upgrade”Run these commands from the production Compose file directory. If you do not have a deployment directory yet, first get docker-compose.yml, env examples, and the init script from Docker Compose Deployment.
- Pull the new image.
- Back up database and secrets.
- Run
docker compose config. - Optionally run
synctv db migrateas a release preflight. - Restart the service. Startup applies pending migrations automatically.
- Check
/health/ready, login, WebSocket, providers, and metrics.
Common commands:
docker compose pulldocker compose up -ddocker compose logs -f synctvHelm Upgrade
Section titled “Helm Upgrade”helm lint ./helm/synctvhelm template synctv ./helm/synctv -f values.production.yamlCheck that HTTP Service and gRPC Service are separate; HTTP Ingress and gRPC Ingress are separate; the gRPC Ingress sets nginx.ingress.kubernetes.io/backend-protocol: "GRPC"; and secrets, volumes, env, ServiceMonitor, or VMServiceScrape match expectations.
helm upgrade --install synctv ./helm/synctv \ -n synctv \ -f values.production.yamlAfter release:
kubectl -n synctv rollout status deploy/synctvkubectl -n synctv logs deploy/synctv --tail=200kubectl -n synctv get ingress,svc,podRolling Updates and Long Connections
Section titled “Rolling Updates and Long Connections”SyncTV has WebSocket, HTTP-FLV, HLS, gRPC streams, and streaming proxy requests. Rolling updates need enough drain time.
Release rules:
- Align
server.shutdown_drain_timeout_secondswith KubernetesterminationGracePeriodSeconds. - Make readiness fail quickly once shutdown starts.
- Do not set
terminationGracePeriodSecondsshorter than the drain timeout. - For livestream or heavy WebSocket deployments, release during low-traffic windows.
Configuration Change Strategy
Section titled “Configuration Change Strategy”Do not copy the full default template blindly. First save the effective configuration:
synctv --config /etc/synctv/synctv.yaml config show --output yaml > effective-before.yamlThen modify only values you intentionally own:
- Secrets and secret file paths.
- Database, Redis, SMTP, OAuth2, WebAuthn.
- Ports, domains, CORS, trusted proxies.
- Cluster, shared HLS storage, file-backed slice cache.
- Metrics, log format, and rate limits.
Rollback
Section titled “Rollback”Before rolling back, classify the situation:
| Situation | Guidance |
|---|---|
| Only config or image changed and the target version has no new migrations | Roll back through the deployment system |
| The new version started and ran automatic migrations, but the old version supports the new schema | Roll back image and watch logs closely |
| The new version ran an irreversible migration | Prefer forward fix; if rollback is required, restore database backup |
| Secret was rotated incorrectly | Restore the old secret and restart service |
After rollback:
synctv db statussynctv config validate --strictcurl -fsS http://localhost:8080/health/readyPost-Release Validation
Section titled “Post-Release Validation”Confirm at least:
- New pods or containers are ready.
/health/readysucceeds.- Root/admin users can log in.
- 2FA-enabled users can complete MFA.
- OAuth2, WebAuthn, and email codes work if enabled.
- Room WebSocket sync works.
- Provider direct and proxy paths work.
- Metrics are scraped.
- Logs do not show sustained migration, Redis, database, or provider errors.
- If capacity or connection behavior changed, revisit database connections, Redis, WebSocket, and proxy bandwidth with Capacity Planning.