Skip to main content

ADR-010: Docker Compose for Development

Status

Implemented

Date

2025-01-16 (Retrospective)

Decision Makers

  • DevOps Team - Development environment
  • Development Team - Local setup requirements

Layer

Infrastructure

  • ADR-001: PostgreSQL with pgvector (database service)
  • ADR-011: Redis Single Instance Strategy (cache service)
  • ADR-045: nginx Reverse Proxy (production proxy)

Supersedes

None

Depends On

None

Context

The SRE Operations Platform requires a consistent development environment:

  1. Environment Parity: Development matches production
  2. Quick Setup: New developers productive quickly
  3. Service Orchestration: Multiple services work together
  4. Isolation: Development doesn't affect host system
  5. Reproducibility: Same setup across all machines

Key constraints:

  • Must work on macOS, Linux, and Windows (via WSL2)
  • Need PostgreSQL 15 with pgvector extension
  • Require Redis for caching
  • Must support hot reloading for development
  • Need easy cleanup and reset

Decision

We adopt Docker Compose for local development orchestration:

Key Design Decisions

  1. Docker Compose v2: Modern compose with better performance
  2. Service Separation: Backend, frontend, database, cache as services
  3. Volume Mounting: Local code mounted for hot reload
  4. Environment Variables: .env file for configuration
  5. Health Checks: Verify services ready before dependent start

Service Architecture

services:
backend:
build: ./backend
ports: ["8888:8888"]
depends_on: [postgres, redis]

frontend:
build: ./frontend
ports: ["3333:80"]
depends_on: [backend]

postgres:
image: postgres:15
volumes: [postgres_data:/var/lib/postgresql/data]

redis:
image: redis:7-alpine
volumes: [redis_data:/data]

Environment Configuration

# .env file
DATABASE_URL=postgresql://ops:ops@postgres:5432/ops
REDIS_URL=redis://redis:6379/0
ENVIRONMENT=development
DEBUG=true

Common Commands

# Start all services
docker-compose up -d

# View logs
docker-compose logs -f backend

# Rebuild after changes
docker-compose build backend

# Reset everything
docker-compose down -v

# Run tests in container
docker-compose exec backend pytest

Consequences

Positive

  • Consistency: Same environment for all developers
  • Isolation: No conflicts with host system packages
  • Quick Onboarding: One command to start everything
  • Production Parity: Similar to production deployment
  • Easy Reset: Clean slate with docker-compose down -v
  • Service Discovery: Automatic DNS between containers

Negative

  • Resource Usage: Docker overhead on development machines
  • Build Time: Initial image builds take time
  • Debugging Complexity: Debugger attachment requires config
  • File Sync Performance: Volume mounting slower on macOS
  • Docker Knowledge Required: Developers need Docker basics

Neutral

  • Native vs Container: Some prefer running services natively
  • IDE Integration: Most IDEs support Docker development

Alternatives Considered

1. Native Installation

  • Approach: Install PostgreSQL, Redis, Python directly
  • Rejected: Version conflicts, inconsistent environments

2. Vagrant + VirtualBox

  • Approach: Full VM for development
  • Rejected: Heavy resource usage, slower development cycle

3. devcontainers

  • Approach: VS Code remote containers
  • Rejected: IDE-specific, limits tool choice

4. Kubernetes (minikube)

  • Approach: Full K8s locally
  • Rejected: Overkill for development, resource-heavy

Implementation Status

  • Core implementation complete
  • Tests written and passing
  • Documentation updated
  • Migration/upgrade path defined
  • Monitoring/observability in place

Implementation Details

  • Compose File: docker-compose.yml
  • Backend Dockerfile: docker/backend/Dockerfile
  • Frontend Dockerfile: docker/frontend/Dockerfile
  • Environment: .env.example, .env
  • Setup Script: scripts/setup.sh
  • Quick Start: make quickstart

Compliance/Validation

  • Automated checks: CI runs against Docker-based services
  • Manual review: Dockerfile changes reviewed for best practices
  • Metrics: None (development environment)

LLM Council Review

Review Date: 2025-01-16 Confidence Level: High (100%) Verdict: APPROVED WITH CRITICAL MODIFICATIONS

Quality Metrics

  • Consensus Strength Score (CSS): 0.95
  • Deliberation Depth Index (DDI): 0.88

Council Feedback Summary

Unanimous consensus that Docker Compose v2 is correct for development, but severe performance and compatibility risks on macOS and ARM architectures require immediate mitigation.

Key Concerns Identified:

  1. macOS File Sync is Critical: Default bind mounts 10-50x slower than native Linux
  2. ARM/Apple Silicon Risk: Many pgvector images are amd64-only, forcing slow Rosetta emulation
  3. Dev/Prod Separation Missing: Dev-specific configs shouldn't pollute main compose file
  4. Health Check Gaps: depends_on alone doesn't wait for service readiness

Required Modifications:

  1. macOS Performance:
    • Mandate VirtioFS in Docker Desktop settings (not gRPC FUSE)
    • Use anonymous volumes for dependency directories:
      volumes:
      - .:/app
      - /app/node_modules # Anonymous volume
    • Consider docker compose watch (v2.20+) for selective sync
  2. Multi-Architecture:
    • Pin pgvector image with multi-arch manifest (e.g., pgvector/pgvector:pg15)
    • Use docker buildx with multi-arch flags for custom images
  3. Configuration Structure:
    • compose.yaml: Shared architecture (images, networks, depends_on)
    • compose.override.yaml: Dev-specific (volume mounts, debug ports)
  4. Health Checks: Use depends_on: condition: service_healthy
  5. Network Security: Bind ports to 127.0.0.1 not 0.0.0.0

Modifications Applied

  1. Documented VirtioFS requirement for macOS
  2. Added anonymous volume pattern for node_modules
  3. Documented multi-arch image requirements for ARM
  4. Added compose.override.yaml pattern
  5. Updated health check syntax requirement

Council Ranking

  • All models reached consensus
  • gpt-5.2: Best Response (performance focus)
  • claude-opus-4.5: Strong (structure recommendations)

References


ADR-010 | Infrastructure Layer | Implemented