Deployment
Build, migrate, deploy, verify, and roll back without exposing test surfaces.
This page is the production rollout checklist for the service image, database schema, runtime configuration, and public documentation site.
Environment Layout
| Environment | Static config | Runtime values | Expected use |
|---|---|---|---|
| Local process | configs/static_config.yaml |
configs/config_vars.yaml |
Manual development and API poking. |
| Dev Docker profile | configs/static_config.yaml |
configs/config_vars.docker.yaml, copied from example |
Containerized development with source mounted. |
| Production Docker profile | configs/static_config.prod.yaml |
External SMIRKLY_CONFIG_VARS_PATH and SMIRKLY_SECRETS_PATH |
Release image without source mount or tests-control endpoints; dynamic config updater/cache enabled. |
Build and Release Gate
A release candidate should build the service, compile SQL query headers, run unit tests, run the functional testsuite as a non-root user, and validate the OpenAPI YAML before deployment.
cmake --preset debug
cmake --build build-debug --parallel 2 --target smirkly-auth smirkly-auth_unittest
# Run from a non-root user; testsuite PostgreSQL initdb refuses root.
ctest --test-dir build-debug --output-on-failure
python3 -c "import yaml; yaml.safe_load(open('openapi/auth-v0.yaml'))"
The GitHub Pages workflow publishes docs/ plus the current openapi/auth-v0.yaml, so API
docs and the deployed contract move together.
Database Migrations
- Run the migration job before starting a service version that depends on new schema.
- Keep
MIGRATE_DATABASE_URLand servicepostgres-dbconnectionpointed at the same database; both should come from the deployment secret/config source. - Do not run application schema from Postgres init scripts in production; use versioned migrations.
- For local databases created before migration tracking, recreate the volume or baseline it manually after checking schema state.
docker compose --profile dev run --rm smirkly-migrate-dev
SMIRKLY_CONFIG_VARS_PATH=/etc/smirkly-auth/config_vars.yaml \
SMIRKLY_SECRETS_PATH=/run/secrets/smirkly-auth \
docker compose --profile prod up --build -d smirkly-auth
Production Container Rules
- Use the release image and
configs/static_config.prod.yaml. - Run the application as the image's unprivileged
smirkly-authuser. - Mount writable persistent storage at
/var/cache/smirkly-authfor the dynamic-config fallback cache. - Mount JWT keys and generated runtime config at deploy time through
SMIRKLY_SECRETS_PATHandSMIRKLY_CONFIG_VARS_PATH. - Build release images with
SMIRKLY_AUTH_ENABLE_TEST_CONTROL=OFF; keep tests-control and fake-mode endpoints out of production. - Expose the service only through TLS-terminating ingress or a private service mesh.
- Set resource limits so userver congestion control reflects real CPU constraints.
- Keep the monitor listener private; route
/health/live,/health/ready, and/service/monitoronly through internal health/metrics infrastructure. - Roll out auth/outbox policy through config-service dynamic config, backed by
dynamic-config.fs-cache-path; roll out secrets and thread-count changes through deploy config plus restart. - Use
configs/dynamic_config/values.example.jsonas the initial config-service seed shape; live config-service responses must followconfigs/dynamic_config/config_service_response.example.json.
Rollout Sequence
- Build and test the release candidate.
- Generate environment-specific
config_vars.yamlfrom the secret store and expose it throughSMIRKLY_CONFIG_VARS_PATH. Useconfigs/config_vars.prod.example.yamlonly as a tracked shape example. - Seed or update config-service with validated auth/outbox dynamic config values.
- Run migrations once per database.
- Start the new service version with
static_config.prod.yaml. - Check JWKS, sign-up, sign-in, refresh, logout, and email verification smoke tests.
- Watch logs, SMTP outbox backlog, DB errors, latency, and 4xx/5xx rate for the rollout window.
Rollback
Prefer forward-compatible migrations. If rollback is required, stop the new service version first, deploy the previous image with its matching runtime config, and only then decide whether a down migration is safe. Never run a destructive down migration while a newer binary can still write to the database.