Skip to main content

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:

  1. project.conf: Metadata for the local orchestrator (priority, persistence, enable/disable).
  2. docker-compose.yml: Container definition (attach to the shared network from DOCKER_NETWORK_NAME).
  3. .env.template (preferred) or .env.example: Variables required by the service.
  4. run.sh: Optional wrapper for service-local commands (the repo uses ./infra as 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 generate should produce ./<project>/.env without 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: 60s for anything that rarely fails (internal sidecars, DBs, services gated only by depends_on at startup). 30s is 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/...' beat python -c "..." or spinning up a DB client — the latter pay interpreter/client startup cost on every single run, forever.
  • retries and timeout don't drive steady-state cost, interval does — when tuning for CPU, that's the one to move.

️ Global Tooling for Developers​

  • ./infra env check validates missing keys.
  • ./infra test health runs safe checks.
  • ./infra test infra runs a full destructive validation.