ADR 0004 — Local Docker scaler + Kubernetes HPA¶
- Status: Accepted
- Date: 2026-04-26
- Deciders: André Luiz Gallon
Context¶
Operators need to change the running agent count by moving a slider on
/agents. There are two deployment modes:
- Docker Compose on a single developer workstation.
- Kubernetes in production, scaling 1 → 300.
We did not want the same code path to control both, because the
abstractions are very different (docker compose --scale agent=N vs.
kubectl scale deployment/web-agent --replicas=N).
Decision¶
- Docker Compose: ship an opt-in but on-by-default in
.env.exampleoverride (docker-compose.scaler.yml) that mounts/var/run/docker.sockinto the dashboard container. The dashboard talks to the Docker Engine API to reconcile the agent service. Activated viaCOMPOSE_FILE=docker-compose.yml:docker-compose.scaler.yml. - Kubernetes: ship a
HorizontalPodAutoscalerwithminReplicas: 1, maxReplicas: 300on CPU + memory ink8s/20-agent-deployment.yaml. The dashboard does not call the Kubernetes API directly; it persists the desired count tocluster_config.desired_agent_count, and operators wire the HPA metrics or usekubectl scalefor manual overrides. - Both modes are documented in the README under Scaling the fleet → Local and Production deployment on Kubernetes.
Consequences¶
- ✅ Operators get a real one-click scaler in the local dev story.
- ✅ Production stays on the well-known HPA path; nothing weird happens at the cluster level.
- ⚠️ The local scaler grants the dashboard FULL control of the host Docker daemon. Documented loudly in the override and disabled by default on shared hosts.
- ⚠️ In Linux the dashboard must join the host's
dockergroup;scripts/init-env.shdetects the rightDOCKER_GID.
Alternatives considered¶
- Single code path that uses Kubernetes API everywhere — rejected because requiring a kubelet on developer workstations defeats the point of the docker-compose path.
- External
scripts/scale-local.sh— kept as a fallback for users that don't want the socket mount, but the embedded scaler is the default for ergonomics.