services: # ── Always-on infrastructure ────────────────────────────── router: image: nginx:alpine restart: unless-stopped ports: - "5000:80" volumes: - ./router/default.conf:/etc/nginx/conf.d/default.conf:ro networks: - net healthcheck: test: ["CMD", "nginx", "-t"] interval: 30s timeout: 5s litestream: image: litestream/litestream:latest restart: unless-stopped command: replicate -config /etc/litestream.yml volumes: - app-data:/app/data - ./litestream.yml:/etc/litestream.yml:ro # ── Blue slot ───────────────────────────────────────────── blue-app: profiles: ["blue"] build: context: . restart: unless-stopped env_file: ./.env environment: - DATABASE_PATH=/app/data/app.db volumes: - app-data:/app/data networks: - net healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')"] interval: 10s timeout: 5s retries: 3 start_period: 15s blue-worker: profiles: ["blue"] build: context: . restart: unless-stopped command: python -m beanflows.worker env_file: ./.env environment: - DATABASE_PATH=/app/data/app.db volumes: - app-data:/app/data networks: - net blue-scheduler: profiles: ["blue"] build: context: . restart: unless-stopped command: python -m beanflows.worker scheduler env_file: ./.env environment: - DATABASE_PATH=/app/data/app.db volumes: - app-data:/app/data networks: - net # ── Green slot ──────────────────────────────────────────── green-app: profiles: ["green"] build: context: . restart: unless-stopped env_file: ./.env environment: - DATABASE_PATH=/app/data/app.db volumes: - app-data:/app/data networks: - net healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5000/health')"] interval: 10s timeout: 5s retries: 3 start_period: 15s green-worker: profiles: ["green"] build: context: . restart: unless-stopped command: python -m beanflows.worker env_file: ./.env environment: - DATABASE_PATH=/app/data/app.db volumes: - app-data:/app/data networks: - net green-scheduler: profiles: ["green"] build: context: . restart: unless-stopped command: python -m beanflows.worker scheduler env_file: ./.env environment: - DATABASE_PATH=/app/data/app.db volumes: - app-data:/app/data networks: - net volumes: app-data: networks: net: