# Secure Homelab Docker Compose Configuration # Use with: docker-compose -f docker-compose.yml -f docker-compose.homelab-secure.yml up -d services: api-server: build: context: ${FETCHML_REPO_ROOT:-..} dockerfile: ${FETCHML_REPO_ROOT:-..}/build/docker/simple.Dockerfile container_name: ml-experiments-api ports: - "9101:9101" - "9100:9100" # Prometheus metrics endpoint volumes: - ${FETCHML_REPO_ROOT:-..}/data/homelab/experiments:/data/experiments - ${FETCHML_REPO_ROOT:-..}/data/homelab/active:/data/active - ${FETCHML_REPO_ROOT:-..}/data/homelab/logs:/logs - ${FETCHML_REPO_ROOT:-..}/ssl:/app/ssl:ro - ${FETCHML_REPO_ROOT:-..}/configs/api/homelab-secure.yaml:/app/configs/api/prod.yaml:ro - ${FETCHML_REPO_ROOT:-..}/.env.secure:/app/.env.secure:ro depends_on: redis: condition: service_healthy restart: unless-stopped environment: - LOG_LEVEL=info # Load secure environment variables - JWT_SECRET_FILE=/app/.env.secure healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9101/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s labels: logging: "promtail" job: "api-server" command: ["/bin/sh", "-c", "mkdir -p /data/active/datasets /data/active/snapshots && exec /usr/local/bin/api-server -config /app/configs/api/prod.yaml"] networks: - ml-experiments-network # Add internal network for secure communication - ml-backend-network minio: image: minio/minio:latest container_name: ml-experiments-minio ports: - "9000:9000" - "9001:9001" volumes: - ${FETCHML_REPO_ROOT:-..}/data/homelab/minio:/data environment: - MINIO_ROOT_USER=${MINIO_ROOT_USER:-minioadmin} - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioadmin123} command: ["server", "/data", "--console-address", ":9001"] restart: unless-stopped networks: - ml-backend-network minio-init: image: alpine:3.19 container_name: ml-experiments-minio-init depends_on: - minio entrypoint: ["/bin/sh", "-c"] command: - | apk add --no-cache ca-certificates curl >/dev/null curl -fsSL -o /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc chmod +x /usr/local/bin/mc mc alias set local http://minio:9000 ${MINIO_ROOT_USER:-minioadmin} ${MINIO_ROOT_PASSWORD:-minioadmin123} # Skip if bucket already exists if mc ls local/fetchml-snapshots 2>/dev/null; then echo "Bucket fetchml-snapshots already exists, skipping init" exit 0 fi mc mb -p local/fetchml-snapshots || true restart: "no" networks: - ml-backend-network worker: build: context: ${FETCHML_REPO_ROOT:-..} dockerfile: ${FETCHML_REPO_ROOT:-..}/build/docker/simple.Dockerfile container_name: ml-experiments-worker volumes: - ${FETCHML_REPO_ROOT:-..}/data/homelab/experiments:/app/data/experiments - ${FETCHML_REPO_ROOT:-..}/data/homelab/active:/data/active - ${FETCHML_REPO_ROOT:-..}/data/homelab/logs:/logs - ${FETCHML_REPO_ROOT:-..}/configs/workers/homelab-secure.yaml:/app/configs/worker.yaml depends_on: redis: condition: service_healthy api-server: condition: service_healthy minio-init: condition: service_started restart: unless-stopped environment: - LOG_LEVEL=info - MINIO_ROOT_USER=${MINIO_ROOT_USER:-minioadmin} - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioadmin123} - REDIS_PASSWORD=${REDIS_PASSWORD} privileged: true command: ["/usr/local/bin/worker", "-config", "/app/configs/worker.yaml"] networks: - ml-backend-network caddy: image: caddy:2-alpine container_name: ml-experiments-caddy restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ${FETCHML_REPO_ROOT:-..}/deployments/Caddyfile.homelab-secure:/etc/caddy/Caddyfile:ro - ${FETCHML_REPO_ROOT:-..}/ssl:/etc/caddy/ssl:ro - ${FETCHML_REPO_ROOT:-..}/data/homelab/caddy/data:/data - ${FETCHML_REPO_ROOT:-..}/data/homelab/caddy/config:/config environment: - FETCHML_DOMAIN=${FETCHML_DOMAIN:-ml.local} depends_on: api-server: condition: service_healthy networks: - ml-experiments-network # Redis with authentication redis: image: redis:7-alpine container_name: ml-experiments-redis user: "999:999" ports: - "127.0.0.1:6379:6379" # Bind to localhost only volumes: - ${FETCHML_REPO_ROOT:-..}/data/homelab/redis:/data - ${FETCHML_REPO_ROOT:-..}/redis/redis-secure.conf:/usr/local/etc/redis/redis.conf:ro restart: unless-stopped command: redis-server /usr/local/etc/redis/redis.conf --requirepass ${REDIS_PASSWORD} healthcheck: test: ["CMD", "redis-cli", "--no-auth-warning", "-a", "${REDIS_PASSWORD}", "ping"] interval: 30s timeout: 10s retries: 3 networks: - ml-backend-network environment: - REDIS_PASSWORD=${REDIS_PASSWORD} volumes: {} networks: ml-experiments-network: driver: bridge ml-backend-network: driver: bridge