name: aline-brand-workbench services: gateway: image: nginx:1.27-alpine ports: - "${GATEWAY_PORT:-8080}:80" volumes: - ./infra/nginx/nginx.conf:/etc/nginx/nginx.conf:ro depends_on: web: condition: service_healthy api: condition: service_healthy restart: unless-stopped web: build: context: . dockerfile: infra/docker/web.Dockerfile environment: API_INTERNAL_URL: http://api:8000 NEXT_PUBLIC_API_BASE_URL: /api/v1 NEXT_TELEMETRY_DISABLED: "1" command: npm run dev --workspace @aline/web -- --hostname 0.0.0.0 ports: - "127.0.0.1:${WEB_PORT:-3000}:3000" volumes: - ./apps/web:/workspace/apps/web - ./contracts:/workspace/contracts:ro healthcheck: test: [ "CMD", "node", "-e", "fetch('http://localhost:3000').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))" ] interval: 10s timeout: 5s retries: 12 start_period: 20s restart: unless-stopped api: build: context: . dockerfile: infra/docker/python.Dockerfile env_file: .env command: >- sh -c "uv run alembic upgrade head && exec uv run uvicorn apps.api.app.main:app --host 0.0.0.0 --port 8000" ports: - "127.0.0.1:${API_EXPOSE_PORT:-8000}:8000" volumes: - ./apps:/workspace/apps - ./backend:/workspace/backend - ./contracts:/workspace/contracts:ro depends_on: postgres: condition: service_healthy redis: condition: service_healthy minio-init: condition: service_completed_successfully healthcheck: test: [ "CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/v1/health/live')" ] interval: 10s timeout: 5s retries: 12 start_period: 10s restart: unless-stopped worker: build: context: . dockerfile: infra/docker/python.Dockerfile command: uv run celery -A apps.api.app.celery_app.celery_app worker --loglevel=INFO --concurrency=2 env_file: .env volumes: - ./apps:/workspace/apps - ./backend:/workspace/backend - ./contracts:/workspace/contracts:ro depends_on: postgres: condition: service_healthy redis: condition: service_healthy minio-init: condition: service_completed_successfully restart: unless-stopped postgres: image: postgres:17-alpine environment: POSTGRES_DB: brand_agent POSTGRES_USER: brand_agent POSTGRES_PASSWORD: brand_agent ports: - "127.0.0.1:${POSTGRES_EXPOSE_PORT:-5432}:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U brand_agent -d brand_agent"] interval: 5s timeout: 5s retries: 20 restart: unless-stopped redis: image: redis:7-alpine command: redis-server --appendonly yes ports: - "127.0.0.1:${REDIS_EXPOSE_PORT:-6379}:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 20 restart: unless-stopped minio: image: minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${S3_ACCESS_KEY_ID:-brand-agent-local} MINIO_ROOT_PASSWORD: ${S3_SECRET_ACCESS_KEY:-brand-agent-local-secret} ports: - "127.0.0.1:${MINIO_API_PORT:-9000}:9000" - "127.0.0.1:${MINIO_CONSOLE_PORT:-9001}:9001" volumes: - minio_data:/data restart: unless-stopped minio-init: image: minio/mc@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727 depends_on: - minio environment: S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID:-brand-agent-local} S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY:-brand-agent-local-secret} S3_BUCKET: ${S3_BUCKET:-brand-agent-local} entrypoint: - /bin/sh - -c - | until mc alias set local http://minio:9000 "$${S3_ACCESS_KEY_ID}" "$${S3_SECRET_ACCESS_KEY}"; do sleep 2; done mc mb --ignore-existing "local/$${S3_BUCKET}" mc anonymous set private "local/$${S3_BUCKET}" volumes: postgres_data: redis_data: minio_data: