feat(compose): dev stack for orchestrator + actuator#27
Conversation
|
@copilot what work did you do? |
Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com>
I implemented a Docker Compose development stack for local testing of orchestrator-ren and actuator-bus services: Created Files:
Modified Files:
Services Configuration:
Validation: Commit: ef6873e |
There was a problem hiding this comment.
@copilot Requesting changes:
✅ What looks good
Root compose.yaml + dev/compose/docker-compose.yml mirror each other and bring up orchestrator-ren (8000) and actuator-bus (8010→8001).
GitHub
Added Makefile shortcuts (up/down/logs/compose-test/compose-validate) and README doc hooks.
GitHub
Minimal Python 3.11-slim Dockerfiles per service with healthchecks.
GitHub
⚙️ Nits / consistency
Health endpoint: healthchecks hit / right now; our convention has been /healthz.
Either expose /healthz in both services and update the compose healthchecks, or explicitly state in docs that / is our health route and keep it consistent.
GitHub
Compose duplication: root compose.yaml and dev/compose/docker-compose.yml are nearly identical.
Suggest: keep one source of truth (prefer dev/compose/docker-compose.yml) and have the root file include it or document a single entrypoint to avoid drift.
GitHub
depends_on (health): containers may start before neighbors are healthy.
Optional but helpful: depends_on: condition: service_healthy to make dev spin-ups less flaky.
.dockerignore (missing): images will include .venv, pycache, etc.
Add a repo-level .dockerignore and/or service-level ones:
.venv
pycache/
*.pyc
.pytest_cache/
logs/
.git
This shrinks images and speeds builds.
Dockerfile polish (tiny):
Add:
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
Pin uvicorn in requirements.txt (avoids surprise breaks).
Makefile portability: current cd dev\compose paths are Windows-style.
Use / so it works on macOS/Linux too:
cd dev/compose && docker compose up -d --build
README ports: confirm ports match compose (8000 for orchestrator, 8010 external for actuator mapping to 8001). The doc looks aligned; just keep that consistent as you tweak health routes.
GitHub
🧪 CI hook (quick win)
Add a tiny smoke job so PRs prove the stack at least parses and builds:
.github/workflows/compose-smoke.yml
name: Compose Smoke
on: [pull_request]
jobs:
compose:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- run: docker compose -f dev/compose/docker-compose.yml config
- run: docker compose -f dev/compose/docker-compose.yml build
✅ Merge gate (DoD for this PR)
Decide on /healthz vs / and align compose + services
Add .dockerignore
Makefile paths POSIX-friendly
Optional: depends_on with service_healthy
(Nice-to-have) add the CI smoke workflow above
|
@copilot did you address the requested changes? |
…ths, CI Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com>
Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com>
... All requested changes have been implemented: ✅ Health endpoints: Added All services build, pass health checks, and startup in correct order. Commits: 46c75d6 (feedback), c14aef6 (security)
Yes, all requested changes have been addressed and tested. See my response to comment #3448705391 for the complete list. |
|
@copilot there was a failure on the checks, for compose smoke / compose, can you take a look at that? |
Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com>
Fixed the CI workflow issue. The problem was a race condition in the health check wait logic: Issue: The workflow used Fix:
Tested locally multiple times - services now reliably reach healthy status. The workflow should pass on the next CI run. Commit: 86dba4b |
|
@copilot Added .dockerignore at repo root (shrinks images, faster builds). Health checks standardized on /healthz and Make targets now use POSIX paths. Added a Compose Smoke CI workflow that validates, builds, brings the stack up, waits for healthy, hits /healthz, and tears down. Great! Documented source of truth as dev/compose/docker-compose.yml with a thin root compose.yaml wrapper. 🧹 Nits (small polish) Pin runtime deps in service requirements.txt for stability (e.g., fastapi~=0.115, uvicorn[standard]~=0.32), then rebuild to lock behavior. (Prevents surprise minor updates breaking healthz.) Tiny Dockerfile envs (helps logs & bytecode noise): ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 Compose healthchecks: you’re verifying in CI with curl, perfect. If you also add container-level healthchecks, ensure the image has a minimal HTTP tool (BusyBox wget -qO- or curl) or use a Python one-liner: CMD ["sh","-c","python - <<'PY'\nimport urllib.request,sys\nimport os\nurl=os.environ.get('HEALTH_URL','http://localhost:8000/healthz')\ntry:\n urllib.request.urlopen(url,timeout=2)\n sys.exit(0)\nexcept:\n sys.exit(1)\nPY"] |
Co-authored-by: macroflux <8061740+macroflux@users.noreply.github.com>
... Addressed the dependency pinning suggestion: Runtime Dependencies Pinned: Changed from
This prevents surprise minor version updates that could break Note on ENV vars: Healthcheck approach: Current Python one-liner using urllib.request works well and requires no additional tools. The suggested alternative is noted for future consideration if we need more flexibility with environment variables. Tested - services build and run successfully with pinned versions. Commit: 7cbbf41 |
Summary
Adds Docker Compose development stack for running orchestrator-ren and actuator-bus locally with shared logging and health monitoring. Implements
/healthzendpoints following MONAD conventions, includes build optimizations, service dependencies, pinned runtime dependencies for stability, and automated CI testing with improved reliability.Molecule Spec
N/A - Infrastructure tooling
ADR Link
N/A - Follows existing service patterns
Contracts
Safety
Tests
/healthzendpointImplementation
Health Endpoints
/healthzendpoint to both services (returns{"status": "healthy"})/healthzfollowing MONAD conventions/endpoint still available for detailed service infoDocker Images
GET /healthzusing stdlib urllib (no external deps)PYTHONDONTWRITEBYTECODE=1,PYTHONUNBUFFERED=1.dockerignoreexcludes .venv, pycache, logs/, .git for smaller imagesDependency Management
Runtime dependencies pinned using
~=(compatible release) operator for stability:=0.38.0, pydantic=2.12.0, requests~=2.32.0=0.38.0, pydantic=2.12.0, pytest~=9.0.0, httpx~=0.28.0This prevents surprise minor version updates that could break
/healthzor other functionality while still allowing patch-level security updates.Compose Stack
Makefile Targets (POSIX-friendly)
CI/CD
.github/workflows/compose-smoke.yml: Automated testing on PRsCI Reliability Improvements
Fixed race condition in health check workflow where the wait logic would succeed prematurely:
grep -q "healthy"to count exactly 2 healthy services:grep -c "healthy") -eq 2depends_onDocumentation
dev/compose/README.md: Quick start, troubleshooting, CI integration examples/healthzas health check endpointRun Ledger (for experiments)
N/A - Infrastructure scaffolding
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.