Eloquent

Documentation

Development Environment

This guide covers the Docker-based local development environment for Go microservices. Use this for starting services, deploying changes, viewing logs, debugging, and performance profiling.

Quick Reference

TaskCommand
Start all servicesmake docker-dev-full
Stop all servicesmake docker-stop
Smart rebuild (auto-detect)make docker-refresh
Rebuild specific servicemake docker-rebuild-{service}
Restart servicemake docker-restart-{service}
View all logsmake docker-logs
View service logsmake docker-logs-{service}
Check statusmake docker-status
Clean everythingmake docker-clean

Infrastructure

Docker runs locally:

  • NATS (port 4222) - Message broker
  • Redis (port 6379) - Cache & sessions

Cloud databases:

  • PostgreSQL - Primary database
  • ClickHouse - Analytics database

Common Operations

Start Services

make docker-dev-full  # Start all services

Stop Services

make docker-stop   # Stop containers (keeps data)
make docker-clean  # Stop + remove volumes

View Logs

make docker-logs           # All services
make docker-logs-agents    # Specific service

docker logs agents --tail 100              # Last 100 lines
docker logs agents 2>&1 | grep -i error    # Search errors

Deploy Code Changes

# After modifying code in services/{name}/
make docker-rebuild-{service}
make docker-logs-{service}  # Verify startup

Development Workflow

# 1. Start services
make docker-dev-full

# 2. Make code changes
vim services/agents/handlers/agent_handlers.go

# 3. Rebuild changed service
make docker-rebuild-agents

# 4. Check logs
make docker-logs-agents

# 5. Test endpoint
curl http://localhost:7700/api/v1/agents

Troubleshooting

Service Shows Unhealthy

# Check health status
docker inspect {service} --format '{{json .State.Health}}' | jq .

# Check what port service listens on
docker exec {service} netstat -tlnp

Common issue: Health check points to wrong port.

Service Won't Start

# Check logs
docker logs {service} --tail 50

# Common issues:
# - Missing env vars: Check dev/env/common.env
# - DB connection failed: Check credentials
# - Port conflict: Check docker ps for conflicts

Service Keeps Restarting

# Check exit code
docker inspect {service} --format '{{.State.ExitCode}}'

# View logs
docker logs {service} 2>&1 | tail -100

Performance Profiling

Quick Resource Check

# All containers at a glance
docker stats --no-stream

# Watch continuously
docker stats

Warning signs:

  • CPU > 10% when idle = potential busy loop
  • Memory growing over time = potential leak

Adding pprof to a Service

import (
    "net/http"
    _ "net/http/pprof"
)

func main() {
    go func() {
        log.Println("Starting pprof server on :6060")
        http.ListenAndServe(":6060", nil)
    }()
    // ... rest of main
}

CPU Profiling

# 30-second CPU profile
curl -o cpu.out "http://localhost:6060/debug/pprof/profile?seconds=30"

# Top CPU consumers
go tool pprof -top cpu.out

Memory Profiling

# Current heap allocations
curl -o heap.out "http://localhost:6060/debug/pprof/heap"

# Top memory consumers
go tool pprof -top heap.out

Service Dependencies

NATS, Redis (infrastructure)
    └── auth
        └── admin, api-gateway, hub, agents
            └── chat (creates CHAT_ANALYTICS stream)
                └── entities, workflow
                    └── remaining services

Configuration Files

FilePurpose
dev/docker-compose.ymlOrchestration entry point
dev/services.ymlService definitions, health checks
dev/env/common.envEnvironment variables
services/{name}/DockerfilePer-service build

Next Steps