Local Development
The local stack mirrors the production topology using Docker Compose for infrastructure and Go's native process runner for services. Tilt adds hot reload and a web UI for day-to-day development.
Prerequisites
| Tool | Version | Notes |
|---|---|---|
| Docker + Docker Compose | Latest stable | Desktop or Engine |
| Go | 1.23+ | go.work workspace used |
| Node.js | 22+ | For apps/web-admin |
| Tilt | Latest | Optional but recommended; curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash |
Quick Start
# 1. Start the full infrastructure stack
make local-up
# 2. Build and start all Go services in the background
make run-all
# Service logs land in /tmp/olly-logs/<service>.log
tail -f /tmp/olly-logs/claims.logmake local-up starts Docker Compose and then runs make keycloak-set-passwords automatically to reset all test user passwords to Olly2026.
Docker Compose Services
The compose file defines a core profile (always on) and an observe profile (--profile observe) for the full observability stack.
| Service | Port(s) | Purpose |
|---|---|---|
| postgres | 5432 | PostgreSQL 16 — shared cluster for all service databases |
| redis (Valkey) | 6380 | Valkey 7 cache — note: 6379 is reserved by SSH tunnel |
| kafka (Redpanda) | 9092 (Kafka API), 9644 (Admin) | Kafka-compatible message broker |
| kafka-ui (Redpanda Console) | 8081 | Web UI for browsing topics and messages |
| keycloak | 8093 | Identity provider — Keycloak 25, imports realm on startup |
| openbao | 8200 | OpenBao secrets engine (dev mode, root token: root) |
| opensearch | 9200 | OpenSearch 2 — provider directory, log analytics |
| temporal | 7233 | Temporal workflow engine |
| temporal-ui | 8233 | Temporal web UI |
| mirth | 8443, 8661 | Mirth Connect EDI engine (NextGen) |
| mailpit | 1025 (SMTP), 8025 (UI) | Local email catcher — inspect outgoing notifications |
| api-docs | 8098 | Scalar API docs (OpenAPI specs) |
| gatus | 8099 | Service health status dashboard |
| otel-collector | 4317 (gRPC), 4318 (HTTP) | OpenTelemetry Collector — always on |
| etcd | 2379 | etcd — APISIX config store |
| apisix | 9080 (HTTP), 9443 (HTTPS), 9180 (Admin) | Apache APISIX API gateway |
| broker-api | 4011 | Broker API service (Docker-managed) |
| document-service | 4009 | Document Service (Docker-managed) |
| member-portal-api | 4012 | Member Portal BFF (Docker-managed) |
| web-admin | 3000 | React Admin web app (Docker-managed) |
| prometheus | 9090 | --profile observe |
| loki | 3100 | --profile observe |
| tempo | 3200 | --profile observe |
| grafana | 3010 | --profile observe |
Go Services (run directly, not via Docker)
These services are started by make run-all as native Go processes:
| Service | Port |
|---|---|
| claims | 4001 |
| eligibility | 4002 |
| enrollment | 4003 |
| billing | 4004 |
| provider | 4005 |
| notifications | 4006 |
| policy-admin | 4007 |
| triage | 4008 |
| care | 4010 |
| group-scheme-service | 4013 |
Make Targets Reference
| Target | Description |
|---|---|
make local-up | Start core Docker Compose stack + reset Keycloak passwords |
make local-up-all | Start core stack + observability profile (Grafana, Tempo, Loki, Prometheus) |
make local-down | Stop stack (volumes preserved) |
make local-down-clean | Stop stack and wipe all volumes |
make keycloak-set-passwords | Reset test user passwords to Olly2026 in the olly realm |
make run-all | Start all Go services in background (logs → /tmp/olly-logs/) |
make stop-all | Stop background Go services |
make build | Build all Go services (go build ./...) |
make test | Run unit tests across all services |
make lint | Run golangci-lint across all services |
make fmt | Run gofmt across all services |
Tilt
Tilt provides hot reload and a developer UI. With the Docker Compose stack already running:
tilt upTilt watches Go source files. When a file changes, it rebuilds the affected service binary and restarts the process — no manual make stop-all && make run-all needed.
Tilt UI: http://localhost:10350 — shows build/run status, live logs, and health for every resource.
Press Ctrl-C to stop Tilt (Docker Compose services continue running).
E2E Tests
E2E tests live in tests/e2e/ as a standalone Go module. They require the local stack and all Go services to be running.
# Run all E2E tests
cd tests/e2e && GOWORK=off go test ./... -v -timeout 90s -count=1
# Run by service
cd tests/e2e && GOWORK=off go test ./claims/... -v -timeout 90s -count=1
# Run specific test pattern
cd tests/e2e && GOWORK=off go test . -run 'TestFullMemberJourney' -v -timeout 90s -count=1GOWORK=off is required to prevent the Go workspace from interfering with the standalone tests/e2e/go.mod. Tests call skipIfUnreachable(t, err) and skip gracefully when services are down, so they do not fail in environments where only some services are running.
Test Credentials
All test users have password Olly2026.
Keycloak admin UI is available at http://localhost:8093 (admin / admin).
MCP Server
The local MCP server for tooling integrations is available at:
http://localhost:3100/mcpDatabase Access
All service databases share the same Postgres instance:
Host: localhost:5432
User: olly
Password: ollyEach service has its own database (claims, eligibility, enrollment, billing, provider, notifications, policy_admin, etc.). Connect with:
psql -h localhost -U olly -d claimsKafka (Redpanda) Access
Browse topics and messages at http://localhost:8081 (Redpanda Console).
Produce/consume via rpk:
rpk topic list --brokers localhost:9092
rpk topic consume claims.claim.submitted --brokers localhost:9092