feat: add Docker support with multi-service compose configuration#161
feat: add Docker support with multi-service compose configuration#161
Conversation
Adds Docker infrastructure for running the full agentd stack in containers, simplifying development setup, CI testing, and cloud deployment. ## Changes - **Dockerfile**: Multi-stage build producing slim runtime image with all service binaries (ask, notify, orchestrator, wrap, hook, monitor) - **docker-compose.yml**: Full service orchestration with: - Shared bridge network for service discovery - Health checks using /health endpoints for all services - Volume mounts for SQLite databases (notify.db, orchestrator.db) - Proper dependency ordering (notify → ask/wrap → orchestrator) - Environment variable configuration matching existing conventions - **docker-compose.dev.yml**: Development override with: - Debug logging enabled - Source code volume mounts for hot reload - Docker Compose watch mode support - **.dockerignore**: Excludes build artifacts, IDE files, and unnecessary files - **README.md**: Comprehensive Docker documentation including: - Quick start guide - Service port reference table - CLI usage with Docker - Development mode instructions - Environment variable reference - Troubleshooting guide ## Service Ports All services run on their standard ports: - ask: 17001 - hook: 17002 - monitor: 17003 - notify: 17004 - wrap: 17005 - orchestrator: 17006 ## Usage ```bash # Build and start all services docker build -t agentd:latest . docker-compose up -d # Development mode with hot reload docker-compose -f docker-compose.yml -f docker-compose.dev.yml up --watch # Check service health agent status ``` Closes #55 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #161 +/- ##
=======================================
Coverage 23.03% 23.03%
=======================================
Files 50 50
Lines 4620 4620
=======================================
Hits 1064 1064
Misses 3556 3556 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
geoffjay
left a comment
There was a problem hiding this comment.
Review: Changes Needed 🔴
This PR has several blocking correctness issues that would prevent the Docker setup from working at all. PR #183 (already reviewed) addresses most of these — the two PRs cover the same feature so these findings should inform which one to land.
🔴 Blocking Issues
1. notify, orchestrator, and wrap bind to 127.0.0.1 — containers unreachable
The compose file sets no HOST variable, so the three services use their hardcoded default of 127.0.0.1. Inside a container, 127.0.0.1 is the container's loopback — no other container or the host can reach it. Every health check, depends_on, and cross-service call will fail immediately.
The current main.rs files already support a HOST env var (added by #183). The fix here is straightforward: add HOST=0.0.0.0 to each service's environment block in docker-compose.yml.
2. wget is not installed in the runtime image — all health checks will fail
The Dockerfile's runtime stage only installs tmux and ca-certificates. The health checks use:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:17004/health"]wget is not present in debian:bookworm-slim. Every health check will immediately exit with exec: wget: not found, containers will never reach healthy, and the depends_on chain will stall. Either install wget (or curl) in the runtime base, or switch to a shell-free check like CMD-SHELL curl -fsS ....
3. Volume mounts don't align with the actual SQLite paths — data is not persisted
The services resolve their database paths via agentd_common::storage::get_db_path, which uses the XDG data directory convention:
Linux default: ~/.local/share/agentd-{service}/{service}.db
→ /home/agentd/.local/share/agentd-notify/notify.db
→ /home/agentd/.local/share/agentd-orchestrator/orchestrator.db
The compose file mounts volumes at /var/lib/agentd/notify and /var/lib/agentd/orchestrator, which are never written to. The databases are written elsewhere and lost on container restart. The fix is to set XDG_DATA_HOME=/data and mount volumes at /data (as PR #183 does).
4. Missing libsqlite3-0 in runtime image
notify and orchestrator use SeaORM with SQLite. If the build links against the system SQLite library (no bundled feature), the runtime container will fail when opening databases because libsqlite3.so.0 isn't installed. Add libsqlite3-0 to the runtime apt-get install list.
5. No build: section in docker-compose.yml — docker compose up fails on a fresh checkout
The compose file uses image: agentd:latest with no build: directive. Running docker compose up on a fresh clone will fail with Unable to find image 'agentd:latest' locally. The user must manually run docker build -t agentd:latest . first. Adding a build: section (or using per-service build targets) makes docker compose up --build work as expected.
🟡 Non-blocking observations
6. WRAP_SERVICE_URL env var is silently ignored by orchestrator
The orchestrator compose environment sets WRAP_SERVICE_URL=http://wrap:17005, but orchestrator/src/main.rs never reads this variable. The orchestrator uses the wrap crate directly as a Rust library (via TmuxManager), not via HTTP. The variable has no effect.
7. hook and monitor are labelled as stubs
Including stub/unimplemented services in the compose file is potentially confusing. Commenting them out (with a note to uncomment when ready) would be cleaner.
8. useradd --shell /bin/bash
debian:bookworm-slim may not include /bin/bash. Use /usr/sbin/nologin for a system service user (PR #183 does this), which is also more appropriate — the agentd user should never need an interactive shell.
9. Rust 1.75 builder
rust:1.75-bookworm is from December 2023. Using rust:1.83-slim-bookworm (or the current stable) would track closer to the version used in CI and reduce the risk of feature-gate mismatches.
Adds Docker infrastructure for running the full agentd stack in containers, simplifying development setup, CI testing, and cloud deployment.
Changes
Service Ports
All services run on their standard ports:
Usage
Closes #55