nexo/services/core/compose/README.md

116 lines
4.7 KiB
Markdown

# Core Compose
This compose file mirrors the current Mattermost-based runtime shape inside the
`services/core` module.
## Local Runtime
```sh
cd services/core/compose
cp -n .env.example .env
docker compose pull
docker compose up -d
```
`latest` is the verified stable pointer for nexo-owned runtime images.
When running or updating, you should run `docker compose pull && docker compose up -d` to fetch the latest stable images.
Runtime state is written to `services/core/data/`, which is ignored by git.
Place push-proxy configuration under
`services/core/data/push-proxy/config/mattermost-push-proxy.json` when FCM smoke
testing is needed.
The default host ports are `18065` for core and `18066` for push-proxy so this
test deployment can run beside the existing Mattermost service.
The Docker network subnet is fixed to `172.38.0.0/16`. Treat this range as
reserved for nexo and do not reuse it for other Docker networks.
## Secret Boundary
Commit only `.env.example`. Keep `.env`, runtime data, logs, push-proxy
credentials, certificates, and license files out of git. If a new credential or
runtime path is added, first add the example variable or documented path here,
then confirm the concrete value or generated file is ignored.
## Smoke Checks
Run these checks after `docker compose up -d`.
```sh
curl -fsS "http://localhost:${NEXO_CORE_PORT:-18065}/api/v4/system/ping"
docker compose exec db pg_isready -U mmuser -d mattermost
curl -fsSI "http://localhost:${NEXO_CORE_PORT:-18065}"
```
The core ping response should report `status` as `OK`, Postgres should accept
connections for the `mattermost` database, and the Mattermost app should return
an HTTP response from the mapped core port.
For the minimum push-proxy smoke, confirm the service is running and the core
service still points at the compose-network DNS name:
```sh
docker compose ps push-proxy
docker compose config | rg --fixed-strings \
"MM_EMAILSETTINGS_PUSHNOTIFICATIONSERVER=http://push-proxy:8066"
```
FCM/APNS credential validation is not part of the default smoke. Run it only
when a real push-proxy config is present outside git.
## Remote Parity
The remote development copy lives under `~/docker/services/nexo/compose`. Local
and remote compose inputs should match unless a work report explicitly records
an intentional temporary drift.
```sh
cd services/core/compose
sha256sum docker-compose.yml .env.example
ssh <host> 'cd ~/docker/services/nexo/compose && sha256sum docker-compose.yml .env.example'
```
The two `sha256sum` outputs should match for both files before remote runtime
smoke is treated as equivalent to local compose smoke.
## Deployment Loop
The compose deployment loop uses the same input contract for dev, test, and
production-like lanes. The lane changes the target and promotion gate, not the
tracked compose file.
### Deployment Lanes
| Lane | Purpose | Promotion gate |
| --- | --- | --- |
| `dev` | Disposable runtime for local feature checks and compose iteration. | Compose config renders, services start, and the smoke checks above pass. |
| `test` | Shared validation lane for upstream baseline or image updates before release notes. | Compose inputs match the candidate branch, images pull by immutable tag or digest, smoke passes, and failures are classified. |
| `production-like` | Internal release rehearsal before a stable pointer is treated as deployable. | Image refs, compose input hashes, secret profile label, smoke evidence, and rollback ref are recorded together. |
Use immutable tags or digests for `test` and `production-like` candidates.
`latest` remains the stable pointer only after the candidate evidence is already
recorded.
### Secret Injection
Start each lane from `.env.example`, then keep the concrete env profile outside
git. A tracked report may name the secret profile label and rotation decision,
but must not include raw values, credential files, hostnames, ports, tokens, or
private endpoint paths.
Push-proxy FCM/APNS credentials stay under ignored runtime data. If a new secret
path is needed, add only the example variable or sanitized path contract here,
then confirm the concrete file remains ignored.
### Rollback Contract
Before applying a candidate, record the previous image refs, compose input
hashes, secret profile label, and data snapshot reference in the private run log.
The public release note or follow-up issue records only the rollback ref,
classification, and sanitized evidence pointer.
A rollback restores the previous image refs and secret profile, starts the same
compose services, and reruns the smoke checks above. If rollback smoke fails,
classify the failure as `server`, `webapp`, `push-proxy`, `SDK contract`, or
`infra`, then open the follow-up before another promotion attempt.