Project Standard (Adding a New Service) — This guide defines the engineering standards and protocols for contributing to the infrastructure. ⬆ índice
Project Standard (Adding a New Service)
This guide defines the engineering standards and protocols for contributing to the infrastructure.
️ The Autonomous Project Protocol
Any service added to this infrastructure must adhere to the Modular Orchestration Protocol. This ensures that the global orchestrator (run.sh) can discover, configure, and manage the service automatically.
Project Structure Requirements
A project directory must contain:
project.conf: Metadata for the local orchestrator (priority, persistence, enable/disable).docker-compose.yml: Container definition (attach to the shared network fromDOCKER_NETWORK_NAME)..env.template(preferred) or.env.example: Variables required by the service.run.sh: Optional wrapper for service-local commands (the repo uses./infraas the main entrypoint).
Tutorial: Adding a New Service
1. Create the Directory
Place your project in the appropriate category folder (e.g., processing/my-new-app).
2. Connect to the shared network
Use the shared network from root .env (DOCKER_NETWORK_NAME).
3. Integrate with env generation
- Put non-secret defaults in
./<project>/.env.template. - Reference global secrets via
${GLOBAL_*}placeholders when needed. ./infra env generateshould produce./<project>/.envwithout manual edits.
Healthcheck intervals (mandatory)
interval: 10s (or anything under 30s) on many containers adds up: each run
is a docker exec — a full runc/containerd process spawn (namespace join,
cgroup setup), heavier still if the test spawns an interpreter (python -c ..., a DB client) instead of a static binary. With 50+ containers on the
host this became a sustained dockerd/containerd CPU load, not a one-off spike
— found on sd2 2026-09-03: 6 mcp_servers/* at interval: 10s running
python -c "import socket; ...", plus sites/cellnex at 10s/15s. Fixed
by moving all of them to interval: 60s.
Rules for any new healthcheck: block:
interval: 60sfor anything that rarely fails (internal sidecars, DBs, services gated only bydepends_onat startup).30sis the hard floor — only go lower with a specific reason written as a comment next to the healthcheck (e.g. a user-facing endpoint where fast failover matters).- Prefer a static binary over an interpreter.
wget --spider/curl/nc/bash -c '</dev/tcp/...'beatpython -c "..."or spinning up a DB client — the latter pay interpreter/client startup cost on every single run, forever. retriesandtimeoutdon't drive steady-state cost,intervaldoes — when tuning for CPU, that's the one to move.
️ Global Tooling for Developers
./infra env checkvalidates missing keys../infra test healthruns safe checks../infra test infraruns a full destructive validation.