Back to Blog

Docker Compose Deployment: One-Click Orchestration for Dev and Test Environments

coomia-dip uses Docker Compose for one-click deployment of development and testing environments, orchestrating 20+ service containers across 8 Layers. The design supports multiple profiles (minimal/standard/full), health-check-based service dependency ordering, configuration overrides, volume management, and GPU support. This article covers orchestration architecture, service definitions, network design, storage strategy, environment management, and operational tooling.

CoomiaPublished on October 2, 20255 min read
Share this articleTwitter / X

Series: S6 Platform Engineering · Article 18 | Level: Advanced | Reading Time: 18 min

Docker Compose Deployment: One-Click Orchestration for Dev and Test Environments

#TL;DR

coomia-dip uses Docker Compose for one-click deployment of development and testing environments, orchestrating 20+ service containers across 8 Layers. The design supports multiple profiles (minimal/standard/full), health-check-based service dependency ordering, configuration overrides, volume management, and GPU support. This article covers orchestration architecture, service definitions, network design, storage strategy, environment management, and operational tooling.

#1. Orchestration Architecture

#1.1 Service Topology

Code
┌──────────────────── Docker Compose ────────────────────┐
│                                                         │
│  ┌─────────────────── Infrastructure ─────────────────┐ │
│  │ PostgreSQL │ Redis │ MinIO │ Kafka │ Nessie        │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  ┌─────────────── Control Layer (B) ─────────────────┐ │
│  │ ontology-service │ schema-registry │ auth-service  │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  ┌──────────────── Data Layer (C) ───────────────────┐ │
│  │ data-service │ iceberg-rest │ materialization     │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  ┌───────────── Intelligence Layer (D/E) ────────────┐ │
│  │ reasoning-service │ agent-runtime │ temporal       │ │
│  └────────────────────────────────────────────────────┘ │
│                                                         │
│  ┌──────────────── Platform (A) ─────────────────────┐ │
│  │ api-gateway │ platform-console                    │ │
│  └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

#1.2 Multi-Profile Support

ProfileServicesUse Case
minimalPostgreSQL, Redis, Ontology Service, Schema RegistryLocal development
standard+ MinIO, Kafka, Nessie, Data/Auth/Reasoning, API GatewayIntegration testing
full+ Agent Runtime, Temporal, Platform ConsoleAcceptance testing

#2. Service Definitions

#2.1 Infrastructure Services

YAML
services:
  postgres:
    image: postgres:16-alpine
    profiles: ["minimal", "standard", "full"]
    environment:
      POSTGRES_DB: coomia-dip
      POSTGRES_USER: onto
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-onto_dev}
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./deployment-Layer/init-scripts:/docker-entrypoint-initdb.d
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U onto"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    profiles: ["minimal", "standard", "full"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s

  minio:
    image: minio/minio:latest
    profiles: ["standard", "full"]
    command: server /data --console-address ":9001"
    volumes:
      - minio_data:/data

#2.2 Platform Services

YAML
  ontology-service:
    build:
      context: ./control-Layer/ontology-service
    profiles: ["minimal", "standard", "full"]
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/coomia-dip
      GRPC_SERVER_PORT: 9090
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "grpc_health_probe", "-addr=:9090"]
      interval: 15s
      retries: 10

  api-gateway:
    build:
      context: ./deployment-Layer/api-gateway
    profiles: ["standard", "full"]
    environment:
      ONTOLOGY_SERVICE_URL: ontology-service:9090
    ports:
      - "${GATEWAY_PORT:-8080}:8080"
    depends_on:
      ontology-service:
        condition: service_healthy

#3. Network Design

#3.1 Service Discovery

Docker Compose provides built-in DNS resolution where services discover each other by container name:

Python
ONTOLOGY_SERVICE_URL = "ontology-service:9090"
SCHEMA_REGISTRY_URL = "schema-registry:9091"

#3.2 Port Mapping Strategy

ServiceContainer PortDefault Host PortOverride Variable
PostgreSQL54325432POSTGRES_PORT
Redis63796379REDIS_PORT
Ontology Service90909090ONTOLOGY_GRPC_PORT
API Gateway80808080GATEWAY_HTTP_PORT
Console30003000CONSOLE_PORT

#4. Environment Management

#4.1 Environment Files

Bash
# .env.development
POSTGRES_PASSWORD=onto_dev
JWT_SECRET=dev-secret-key
LOG_LEVEL=DEBUG

# .env.testing
POSTGRES_PASSWORD=onto_test
LOG_LEVEL=INFO

#4.2 Configuration Overrides

YAML
# docker-compose.override.yml (development overrides)
services:
  ontology-service:
    volumes:
      - ./control-Layer/ontology-service/src:/app/src
    environment:
      SPRING_PROFILES_ACTIVE: dev
    ports:
      - "5005:5005"  # Debug port

  reasoning-service:
    volumes:
      - ./intelligence-Layer/reasoning-service:/app
    command: ["uvicorn", "main:app", "--reload"]

#5. Operational Tooling

#5.1 Management Script

Bash
#!/bin/bash
# scripts/onto-dev.sh

case "$1" in
  up)
    PROFILE=${2:-standard}
    docker compose --profile $PROFILE up -d
    docker compose --profile $PROFILE wait ontology-service
    echo "Platform ready at http://localhost:8080"
    ;;
  down)
    docker compose --profile full down
    ;;
  reset)
    docker compose --profile full down -v
    ;;
  logs)
    docker compose logs -f ${2:-""}
    ;;
  status)
    docker compose ps --format "table {{.Name}}\t{{.Status}}\t{{.Ports}}"
    ;;
  test)
    docker compose --profile standard up -d
    docker compose wait ontology-service
    pytest tests/ -v
    docker compose --profile standard down
    ;;
esac

#6. GPU Support

YAML
# docker-compose.gpu.yml
services:
  reasoning-service:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    environment:
      CUDA_VISIBLE_DEVICES: "0"
      MODEL_DEVICE: "cuda"

#7. Health Check Strategy

YAML
# Infrastructure: fast checks, quick recovery
postgres:
  healthcheck:
    test: ["CMD-SHELL", "pg_isready -U onto"]
    interval: 10s
    timeout: 5s
    retries: 5

# Application: longer intervals, more retries
ontology-service:
  healthcheck:
    test: ["CMD", "grpc_health_probe", "-addr=:9090"]
    interval: 15s
    timeout: 5s
    retries: 10
    start_period: 30s

#8. Resource Limits

YAML
services:
  ontology-service:
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 2G
        reservations:
          cpus: "0.5"
          memory: 512M

#9. Testing

Python
class TestDockerCompose:
    def test_minimal_profile_starts(self):
        result = subprocess.run(
            ["docker", "compose", "--profile", "minimal", "up", "-d"],
            capture_output=True,
        )
        assert result.returncode == 0

    def test_services_healthy(self):
        result = subprocess.run(
            ["docker", "compose", "ps", "--format", "json"],
            capture_output=True, text=True,
        )
        services = json.loads(result.stdout)
        for svc in services:
            if "Health" in svc:
                assert svc["Health"] == "healthy"

    def test_grpc_connectivity(self):
        channel = grpc.insecure_channel("localhost:9090")
        stub = OntologyServiceStub(channel)
        response = stub.HealthCheck(HealthCheckRequest())
        assert response.status == "SERVING"

#10. Production Best Practices

  1. Never hardcode passwords in docker-compose.yml; use .env files
  2. Add .env to .gitignore to prevent secret leaks
  3. Use Docker Secrets or external key management for production
  4. Limit exposed ports to only what is necessary
  5. Set resource limits on all services to prevent resource exhaustion
  6. Configure log rotation to prevent disk space issues

#11. Summary

The coomia-dip Docker Compose deployment provides flexible orchestration from minimal development environments to full testing setups. Key design highlights:

  1. Multi-profile: minimal/standard/full three-tier configuration
  2. Health checks: All services with health checks ensuring startup ordering
  3. Config overrides: Environment variables + override files for flexible configuration
  4. Operational tooling: One-click start/stop/reset/log management scripts
  5. GPU support: Intelligence Layer GPU acceleration configuration

The next article will explore the coomia-dip Kubernetes Operator deployment.