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
| Task | Command |
|---|---|
| Start all services | make docker-dev-full |
| Stop all services | make docker-stop |
| Smart rebuild (auto-detect) | make docker-refresh |
| Rebuild specific service | make docker-rebuild-{service} |
| Restart service | make docker-restart-{service} |
| View all logs | make docker-logs |
| View service logs | make docker-logs-{service} |
| Check status | make docker-status |
| Clean everything | make 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
| File | Purpose |
|---|---|
dev/docker-compose.yml | Orchestration entry point |
dev/services.yml | Service definitions, health checks |
dev/env/common.env | Environment variables |
services/{name}/Dockerfile | Per-service build |
Next Steps
- Backend Services - Creating and modifying services
- API Gateway - Gateway configuration
- Production Deployment - Deploying to production