Skip to content

Authority Doc / Public V1 Environments

The Environment Runbook defines how CoachMe environments are configured, promoted, recovered, and operated.

This page is the Public V1 authority for local, test/CI, staging, and production environment rules across the CoachMe app stack: API, workers, coach web, coach mobile, client mobile, PostgreSQL, Redis/BullMQ, object storage, Keycloak, reverse proxy, configuration, secrets, migrations, deployment gates, backup, restore, and rollback.

AuthorityEnvironmentsDockerSecretsRelease GatesPublic V1

Note

This page does not re-explain the architecture. technical-architecture-plan explains the stack choices; this runbook defines how those choices are configured and operated by environment.

Scope

This runbook owns the environment contract for the future CoachMe application stack and hands off adjacent concerns to the authority pages that define them in detail.

This Runbook Owns

  • Local, test/CI, staging, and production environment tiers.
  • Service topology for the CoachMe app stack.
  • Environment-specific URLs, ports, domains, mobile schemes, and deep-link rules.
  • Public client config, backend runtime config, and secrets.
  • Local bootstrap and reset expectations.
  • Fixture provisioning, reset mechanics, and environment validation.
  • Staging and production provisioning, configuration, deployment, and health mechanics.
  • Migrations, seed data, backup, restore, rollback, and health checks.
  • A small appendix documenting the current static docs-site deployment.

This Runbook Does Not Own

Note

Feature pages may declare that they need storage, queues, workers, or provider config, but this runbook decides the shared environment contract those features depend on.

Environment Model

Public V1 uses four environment tiers with distinct ownership, promotion posture, and data safety rules.

EnvironmentOwnerPurposeData posture
localDeveloperDisposable development stack and app bootstrap.Sample data only; easy reset; no production secrets.
testAutomationTest and CI validation for contracts, migrations, workers, and protocol gates.Deterministic fixtures; isolated services per run.
stagingRelease ownerProduction-like release candidate environment.Versioned synthetic fixtures only; persistent dependencies; restore drills.
productionOperations ownerCustomer-facing runtime.Customer data; audited changes; least-privilege access.

Environment Invariants

  • staging and production are configured through environment files, secrets, and deployment manifests;
  • Public V1 does not use product-admin UI to mutate secrets or core environment behavior;
  • promotion moves the same immutable application artifact where the surface supports promotion, plus reviewed environment-specific configuration;
  • where app-store or native configuration requires a separate production binary, the production candidate is built reproducibly from the same accepted commit, assigned its own digest, and verified before store release without a second source change;
  • production-only secrets never run in local or CI;
  • staging proves migrations, TLS, domains, auth providers, storage, queues, workers, backup, restore, rollback, and smoke tests before production.

Service Topology

The environment contract names the deployable runtime surfaces and dependency services without re-explaining the architecture rationale.

ServiceRole
apiNestJS HTTP API, OpenAPI generation, guards, domain application services.
workerNestJS/BullMQ worker for outbox publishing, reminders, media jobs, push jobs, imports, scheduled materialization, and retryable background work.
webNext.js coach/admin web app.
mobile-coachExpo coach mobile app with generated API clients and environment-specific config.
mobile-clientExpo client/personal mobile app with generated API clients and environment-specific config.
postgrescanonical relational store.
redisBullMQ coordination, short-lived locks, rate-limit counters, and approved cache.
minio or compatible object storagemedia and document bytes.
keycloakidentity provider, external federation, sessions, realm config, and token issuer.
reverse-proxyTLS termination, host routing, request limits, and future WebSocket/SSE allowance if needed.
alloyDocker-managed collector for approved backend logs, application/runtime metrics, and collector self-signals.

Note

Bounded-context structure and stack rationale remain in technical-architecture-plan; this runbook owns the environment-facing contract those components follow.

Local

Local is disposable and optimized for developer bootstrap, inspection, and safe reset.

Local Expectations

  • app dependency services run through Docker Compose: PostgreSQL, Redis, MinIO, and Keycloak;
  • API, worker, and web run natively through pnpm dev for fast reload, and are not containers in the default local stack;
  • a full Compose profile additionally runs API, worker, and web as containers for full-stack and end-to-end runs, so parity is available on demand without slowing daily iteration;
  • Expo coach and client apps point at a local or LAN-accessible API base URL;
  • local uses safe sample credentials and sample data;
  • local can import a development Keycloak realm;
  • local object storage creates required buckets automatically or through an explicit bootstrap command;
  • local reset drops disposable data, queues, and buckets without affecting shared environments;
  • local exposes health checks for API, worker dependencies, database, Redis, object storage, and Keycloak.

Local Must Not

  • local does not use production secrets, production services, or sample data as migration evidence.

Test And CI

Test and CI prove repeatable environment correctness before release-candidate promotion.

  • dependency install with approved package manager and lockfile;
  • lint, typecheck, and unit tests;
  • migrations against empty and upgraded seeded PostgreSQL databases;
  • OpenAPI client generation or validation;
  • REST contract tests;
  • event/outbox retry and idempotency tests;
  • offline-sync replay and conflict protocol tests;
  • worker tests with Redis/BullMQ available;
  • object-storage integration tests for upload intent, metadata, and cleanup;
  • Keycloak test realm/config import or validation;
  • required env validation for missing values and unsafe dummy-secret values.

Staging

Staging is the production-like release-candidate environment that proves operational readiness before production.

  • real TLS and production-shaped hostnames;
  • production-style secrets in the chosen secret mechanism;
  • persistent PostgreSQL, Redis, object storage, and Keycloak;
  • release-candidate config, migrations, workers, scheduled jobs, and OpenAPI clients;
  • mobile deep links and app schemes for staging builds;
  • push-provider sandbox or production-equivalent validation where available;
  • object-storage buckets, upload limits, lifecycle policies, and media worker checks;
  • backup creation and restore drill evidence before production launch;
  • smoke tests for coach web, coach mobile, client mobile, auth, API, queues, media upload, and worker processing;
  • no copied, anonymized, exported, or snapshotted production data; staging uses versioned synthetic fixtures only. This rule is load-bearing for the staging region decision below: synthetic fixtures are not personal data, which is what permits staging to run outside the production data region. Copying a production dump, export, or snapshot onto staging would place regulated client data in an unapproved region and is prohibited.

Staging Topology

Public V1 staging runs on a single operator-controlled VPS rather than a managed platform, matching one-engineer operations and reusing the deployment pattern already proven by the docs site.

ConcernDecision
HostOne Hostinger KVM 4 VPS: 4 vCPU, 16 GB RAM, 200 GB NVMe.
RegionOutside UAE/GCC. Permitted for staging only, and only while the synthetic-fixture rule above holds.
RuntimeDocker Compose running the app-repo stack: PostgreSQL, Redis, Keycloak, API, web, and workers as they exist.
Object storageNot settled by this row. The integration-register approves MinIO for local development only and explicitly withholds staging use, and its staging/production S3-compatible selection is still conditional. Staging object storage needs a register decision before media features are exercised there.
IngressTraefik with the Let's Encrypt cert resolver, following the existing docs-site label pattern.
Hostnamesgrow-pro.cloud subdomains for staging surfaces, giving the real TLS and production-shaped hostnames required above.
Capacity postureThe stack fits the host with headroom. ClamAV is the largest incremental consumer once media scanning lands and must be sized before it is enabled.
ProductionProduction topology and data region remain undecided. This staging choice does not imply or constrain them.

Production

Production protects customer data and requires auditable promotion, recovery, and incident access posture.

  • immutable release artifacts;
  • reviewed deployment manifests and environment config;
  • least-privilege secrets and service credentials;
  • TLS and correct public domains;
  • explicit database backup before risky migrations;
  • migration approval and post-migration smoke checks;
  • health endpoints, Pino logs, OpenTelemetry metrics, Sentry errors/crashes, safe client diagnostics, request ids, whole-workflow correlation ids, and alert destinations; distributed tracing remains Maturity;
  • incident access rules for production secrets, health/nutrition records, media, and support diagnostics;
  • backup retention and restore evidence;
  • rollback or forward-fix plan for every release;
  • no unaudited manual shell edits as the deploy mechanism.

Production Smoke Identities

  • Dedicated synthetic coach and client identities are provisioned only through a reviewed bootstrap script.
  • They remain isolated in a clearly named synthetic workspace and relationship.
  • They cannot discover, select, invite, message, or access real users or real workspaces.
  • Smoke-created records are labeled, bounded, and cleaned through the approved Privacy lifecycle.
  • Credentials remain production secrets and are never stored in release artifacts or test output.

Configuration

Environment behavior is expressed through explicit configuration classes so public client values, backend runtime settings, and secrets stay separate.

ClassExamplesRule
Public client configAPI base URL, app scheme, deep-link domains, supported locales, safe feature flags.May be exposed to web/mobile clients. Must not contain secrets.
Backend runtime configDatabase URL, Redis URL, object-storage endpoint, queue names, CORS origins, token issuer/audience, rate limits, retention windows.Backend-only. May reference secret names but should not leak secret values.
SecretsDatabase passwords, Keycloak admin credentials, OAuth client secrets, signing keys, object-storage credentials, push provider credentials, webhook secrets.Secret manager or deployment secret mechanism only. Never committed. Never bundled into clients.

Secrets

Secret handling is environment-owned and non-negotiable for Public V1.

  • no secrets in Git;
  • no raw secrets in docs examples;
  • no secrets in frontend bundles;
  • no production secrets in local or CI;
  • secret rotation requires a reviewed deployment change and audit evidence;
  • provider credentials live in Keycloak, the deployment secret store, or another approved backend-only secret mechanism;
  • product-admin UI does not mutate Public V1 secrets;
  • support/admin diagnostics redact secret values.

Data State

Runtime state ownership is explicit so supporting systems never become alternate product authorities.

Durable Authorities

  • PostgreSQL owns aggregates, audit, outbox, auth mapping, object metadata, and durable business facts.
  • Keycloak owns credentials, identity federation, token/session mechanics, and realm-level identity configuration.

Supporting Runtime State

  • Redis owns queue coordination and short-lived operational state only.
  • MinIO/S3 owns bytes; PostgreSQL owns metadata, permissions, and lifecycle.
  • Mobile SQLite owns offline drafts and cached slices until server acceptance.

Migrations And Seeds

Schema change, rollback posture, and data seeding rules differ by environment and must be declared up front.

Migration Rules

  • every schema change ships with a forward migration;
  • every migration states its rollback, forward-fix, or restore posture;
  • CI runs migrations against an empty database and an upgraded seeded database;
  • staging runs release-candidate migrations before production;
  • production migrations require backup evidence, operator approval, and smoke-test checkpoints.

Seed Tiers

  • local gets rich demo data;
  • test/CI gets deterministic fixtures only;
  • staging gets release-candidate fixtures and synthetic accounts;
  • production gets bootstrap data only through reviewed scripts or admin runbooks.

Storage And Queues

Object storage and background work are shared environment contracts, not feature-local implementation details.

Object Storage Rules

  • required buckets are declared by environment;
  • Public V1 uses two buckets, one for media and one for documents, so lifecycle, retention, and access policy can differ per class rather than being forced to share one policy; the local bootstrap creates both;
  • the documents-bucket environment variable is added when document handling lands, rather than shipping a required variable no code reads yet;
  • service and region selection is gated on the residency review named in the integration-register; if UAE/GCC residency is required for health-adjacent media, the selected service must expose an in-region endpoint;
  • signed URL TTLs and upload limits are configured per environment;
  • PostgreSQL stores metadata and permissions;
  • media workers handle validation, normalization, scanning, thumbnails, and cleanup where feature pages require them;
  • production bucket permissions follow least privilege;
  • lifecycle and retention rules align with the Privacy And Retention authority.

Queue Rules

  • Redis/BullMQ queues are named consistently by bounded context or operational purpose;
  • workers are separately health-checked from the API;
  • retry, backoff, and dead-letter behavior follows the event/outbox authority where events are involved;
  • failed jobs retain diagnostic context without leaking secrets or unnecessary private data;
  • staging proves scheduled jobs and retry behavior before production.

Mobile Domains

Environment ownership for mobile surfaces covers hostnames, schemes, redirects, and safe bundled config only.

  • API base URLs per environment;
  • app schemes for coach and client apps;
  • universal/app link domains for invitation, login, onboarding, and media flows;
  • OAuth redirect URLs and Keycloak client settings;
  • push notification environment identifiers;
  • build profile names for local, staging, and production;
  • public client config that is safe to bundle;
  • cache purge and app reinstall behavior only at the environment level;
  • offline operation envelopes, SQLite schemas, receipts, and conflict behavior are defined in offline-sync-protocol.

Observability Runtime And Health

This runbook owns the approved collection path, environment isolation, configuration, hardening, and health semantics.

V1 Provider Layout

  • Use one conditional Grafana Cloud stack for staging and production to keep one-engineer operations small.
  • Every production query and alert filters deployment.environment.name=production.
  • Staging and production use separate write credentials. Local and test do not export externally.
  • Sentry uses separate projects for backend API/workers, coach web, coach mobile, and client mobile; environment and release distinguish staging/production.

Collector And Access Hardening

  • Alloy uses the protected restricted Docker API proxy. A direct Docker socket mount, including a read-only mount, is prohibited.
  • Run non-root where supported, drop unused capabilities, use a read-only filesystem, bound memory, and expose no public receiver/UI ports.
  • Use scoped write-only ingestion credentials, named admin accounts, MFA, least privilege, separate admin/ingestion credentials, and provider activity logging.
  • Client Sentry DSNs may be public config only after approval; Grafana credentials, backend tokens, and source-map upload tokens remain secrets.

Environment-owned health semantics

CheckRequired semantics
/health/liveAPI process only; no downstream dependency check.
/health/readyPostgreSQL plus only dependencies required to accept requests safely.
Worker readinessPostgreSQL and Redis/BullMQ through the approved process/container check.
Component/degraded checksKeycloak, object storage, processors, and external providers are reported separately and do not make the API blanket-unready unless the request-acceptance contract requires them.
Exposure and cadencePublic response is minimal; protected detail names dependencies. Internal checks run every 60 seconds. Public synthetics remain Observability-owned.

Container Log Rotation And Disk

Every Docker environment uses the local logging driver with max-size=10m and max-file=3. A reviewed json-file fallback must use the same bounds. Export filesystem use, rotation evidence, Alloy heartbeat, and exporter failures/drops.

Failure Boundary

Collector/provider failure never blocks accepted requests or jobs. Local stdout remains available. Observability owns the 85%/10-minute disk alert and telemetry-pipeline alert; this runbook owns configuration and recovery.

Deployment Gates

Promotion is gated by environment evidence rather than ad hoc confidence.

Configuration validation

Required values, safe URLs, origins, and non-placeholder secrets are present.

Database validation

Migrations apply cleanly and risky changes have backup evidence.

Contract validation

OpenAPI clients are current and REST contract checks pass.

Event validation

Outbox, retry, idempotency, and dead-letter expectations are proven.

Offline validation

Replay, conflict, upload refresh, and mobile smoke checks pass.

Auth validation

Keycloak realm/config import and login flows work for the target environment.

Storage/queue validation

Buckets, limits, queues, workers, and scheduled jobs are healthy.

Observability validation

Launch health, Pino logs, OpenTelemetry metrics, Sentry errors/crashes, safe client diagnostics, identifiers, dashboards, synthetics, and alert destinations are present. Distributed tracing is Maturity.

Note

Detailed release evidence and final promotion approval are defined by the Test And Release Gate; these environment categories already bind Public V1 promotion.

Backup And Restore

Recovery evidence is environment-specific and must account for both relational metadata and stored bytes.

  • backup cadence and retention are defined per environment;
  • local backups are optional and developer-owned;
  • CI state is disposable;
  • staging requires a restore drill before production launch and after material storage or backup changes;
  • production requires at least one successful scheduled backup every 24 hours, a 6-hour grace period, monitored success/failure, and documented restore steps; the stale threshold is 30 hours;
  • object storage and database restore plans account for metadata/byte consistency.

Rollback

Rollback posture is declared before release approval and stays separate from production data repair.

  • app image rollback and config rollback are documented separately;
  • migration rollback is not assumed safe;
  • irreversible or risky migrations require a forward-fix or restore plan before release approval;
  • failed worker/outbox deployments require queue-drain, retry, or pause/resume instructions;
  • rollback is separate from data repair;
  • production data repair requires an audited runbook.

Docs-Site Appendix

This appendix records the current repo deployment reality without treating it as the product application stack.

  • current docker-compose.yml serves the static docs site only;
  • current route is docs.grow-pro.cloud through Traefik labels;
  • current docs service exposes Nginx port 80 inside the container;
  • scripts/deploy-coach-me-docs.sh is a docs-site operational convenience;
  • the docs-site deployment is not the application deployment process;
  • the coach-me app repo now provides its own local application docker-compose.yml (PostgreSQL, Redis, MinIO with bucket bootstrap, and Keycloak with realm import); the docs-site deployment stays separate from it.

This runbook hands off product scope, architecture rationale, protocol detail, privacy policy, observability, and release proof to adjacent docs.

Product OS Home

Entry point for the CoachMe planning set and status summary.

Development Readiness Review

Tracks readiness gaps and cross-system implementation evidence.

Public V1 Scope Contract

Defines the approved Public V1 scope that this environment contract supports.

Technical Architecture Plan

Owns architecture rationale and stack choice explanation.

Workflow State Map

Lifecycle states that environment gates and automation must respect.

Roles And Permissions

Authorization boundaries for runtime access, diagnostics, and support workflows.

API Contract Standard

REST, DTO, OpenAPI, and generated client rules referenced by CI and release gates.

Event And Outbox Standard

Event publisher, consumer, retry, and dead-letter behavior for background work.

Offline Sync Protocol

Mobile SQLite, replay, receipt, and conflict behavior that stays outside this runbook.

Privacy And Retention

Owns retention, legal posture, telemetry classes, and storage lifecycle policy.

Observability Plan

Owns signal semantics, dashboards, alerts, synthetics, objectives, and developer diagnosis playbooks.

Test And Release Gate

Defines executable release evidence, required-check cadence, and final promotion approval.

CoachMe internal planning documentation.