feat(catalog_try): add catalog_try.yml contract to the 5 admin elements
Umbrella: #164
Wave: WAVE_03 (since 2026-05-22)
Cross-repo umbrellas: range42/range42#174, range42/range42-playbooks#62
Problem
After the 5 admin Docker PRs (#148-#152) landed on dev (Cycle D, 2026-05-29),
the catalog-try-list showed them all as L1 (best-effort docker ps -a
fallback) :
[L1] docker/admin/gitea
[L1] docker/admin/gitea-registry
[L1] docker/admin/mattermost
[L1] docker/admin/nextcloud
[L1] docker/admin/rocketchat
L1 is acceptable for a first smoke pass (proves "a container started"), but
each of these services exposes a stable HTTP healthcheck endpoint already
declared in its compose.yml healthcheck block. Promoting them to L2 with a
real HTTP poll closes the gap between "container running" and "service
actually serving traffic".
Solution
Add a per-element catalog_try.yml contract that declares the canonical
HTTP smoke check for each service. All five use service mode with the
endpoint and port taken straight from the contributor's compose healthcheck,
plus a conservative init_timeout per service init profile.
| Element |
Port |
Endpoint |
init_timeout (s) |
Source of truth |
| gitea |
3000 |
/api/v1/version |
90 |
gitea container healthcheck line in compose.yml |
| gitea-registry |
3000 |
/api/v1/version |
90 |
sister of gitea ; same shape |
| mattermost |
8065 |
/api/v4/system/ping |
120 |
mattermost container healthcheck line |
| nextcloud |
8080 |
/status.php |
180 |
host-mapped port 8080->80 ; healthcheck uses /status.php |
| rocketchat |
3000 |
/api/v1/info |
180 |
rocketchat container healthcheck line |
Notes on the choices :
- Smoke semantics :
catalog_try.element_deploy.yml checks status_code: 200 on the URL. It does not parse the body. For Nextcloud specifically,
/status.php returns 200 early in the init (with "installed":false)
and stays 200 once installed ; this is still strict enough to prove
HTTP serving and is a clear improvement over L1.
- init_timeout : capped at 600s by the playbook. The values above are
conservative envelopes based on the cold-start profile of each service
(Mongo + Meteor for Rocket.Chat, PHP-FPM + Postgres + first-run config
for Nextcloud, JS bundle warm-up for Mattermost, image pull + DB seed for
Gitea / Gitea-registry).
- Sister consistency :
gitea-registry mirrors gitea (it is the same
image with GITEA__packages__ENABLED=true ; same init profile, same
endpoint).
Verification
After landing, on the deployer-cli :
range42-context catalog-try-list-admin
Expected : the 5 admin elements switch from L1 (yellow) to L2 (green) :
[L2] docker/admin/gitea
[L2] docker/admin/gitea-registry
[L2] docker/admin/mattermost
[L2] docker/admin/nextcloud
[L2] docker/admin/rocketchat
Each range42-context catalog-try docker/admin/<elem> run then exercises the
HTTP poll task (smoke check - service HTTP polling) instead of the L1
fallback (smoke check - L1 default (docker ps -a)).
Files
03_container_layer/docker/admin/gitea/catalog_try.yml (new)
03_container_layer/docker/admin/gitea-registry/catalog_try.yml (new)
03_container_layer/docker/admin/mattermost/catalog_try.yml (new)
03_container_layer/docker/admin/nextcloud/catalog_try.yml (new)
03_container_layer/docker/admin/rocketchat/catalog_try.yml (new)
References
feat(catalog_try): add catalog_try.yml contract to the 5 admin elements
Problem
After the 5 admin Docker PRs (#148-#152) landed on
dev(Cycle D, 2026-05-29),the catalog-try-list showed them all as L1 (best-effort
docker ps -afallback) :
L1 is acceptable for a first smoke pass (proves "a container started"), but
each of these services exposes a stable HTTP healthcheck endpoint already
declared in its
compose.ymlhealthcheck block. Promoting them to L2 with areal HTTP poll closes the gap between "container running" and "service
actually serving traffic".
Solution
Add a per-element
catalog_try.ymlcontract that declares the canonicalHTTP smoke check for each service. All five use
servicemode with theendpoint and port taken straight from the contributor's compose healthcheck,
plus a conservative init_timeout per service init profile.
/api/v1/versioncompose.yml/api/v1/version/api/v4/system/ping/status.php/api/v1/infoNotes on the choices :
catalog_try.element_deploy.ymlchecksstatus_code: 200on the URL. It does not parse the body. For Nextcloud specifically,/status.phpreturns200early in the init (with"installed":false)and stays
200once installed ; this is still strict enough to proveHTTP serving and is a clear improvement over L1.
conservative envelopes based on the cold-start profile of each service
(Mongo + Meteor for Rocket.Chat, PHP-FPM + Postgres + first-run config
for Nextcloud, JS bundle warm-up for Mattermost, image pull + DB seed for
Gitea / Gitea-registry).
gitea-registrymirrorsgitea(it is the sameimage with
GITEA__packages__ENABLED=true; same init profile, sameendpoint).
Verification
After landing, on the deployer-cli :
Expected : the 5 admin elements switch from L1 (yellow) to L2 (green) :
Each
range42-context catalog-try docker/admin/<elem>run then exercises theHTTP poll task (
smoke check - service HTTP polling) instead of the L1fallback (
smoke check - L1 default (docker ps -a)).Files
03_container_layer/docker/admin/gitea/catalog_try.yml(new)03_container_layer/docker/admin/gitea-registry/catalog_try.yml(new)03_container_layer/docker/admin/mattermost/catalog_try.yml(new)03_container_layer/docker/admin/nextcloud/catalog_try.yml(new)03_container_layer/docker/admin/rocketchat/catalog_try.yml(new)References
dev:docker/_ctf/hello/catalog_try.yml(oneshot mode) +
docker/_ctf/cve/blank_template/catalog_try.yml(service mode). Landed via feat(catalog_try): add catalog_try.yml contract to POC elements (hello + blank_template) #166.
gitea+gitea-registryPOSTGRES_PASSWORD default + range42/range42-playbooks.envauto-seed from.env.example.