services: api: depends_on: postgres: condition: service_healthy redis: condition: service_healthy garage: condition: service_started networks: - app - edge labels: - traefik.enable=true - traefik.http.routers.${TRAEFIK_API_ROUTER_NAME:-multimailer-api}.rule=PathPrefix(`/api`) || Path(`/health`) - traefik.http.routers.${TRAEFIK_API_ROUTER_NAME:-multimailer-api}.entrypoints=web - traefik.http.routers.${TRAEFIK_API_ROUTER_NAME:-multimailer-api}.priority=100 - traefik.http.services.${TRAEFIK_API_SERVICE_NAME:-multimailer-api}.loadbalancer.server.port=8000 worker: depends_on: postgres: condition: service_healthy redis: condition: service_healthy garage: condition: service_started webui: depends_on: api: condition: service_started networks: - app - edge labels: - traefik.enable=true - traefik.http.routers.${TRAEFIK_WEBUI_ROUTER_NAME:-multimailer-webui}.rule=PathPrefix(`/`) - traefik.http.routers.${TRAEFIK_WEBUI_ROUTER_NAME:-multimailer-webui}.entrypoints=web - traefik.http.routers.${TRAEFIK_WEBUI_ROUTER_NAME:-multimailer-webui}.priority=1 - traefik.http.services.${TRAEFIK_WEBUI_SERVICE_NAME:-multimailer-webui}.loadbalancer.server.port=80 traefik: image: traefik:v3.2 command: - --api.dashboard=true - --api.insecure=${TRAEFIK_DASHBOARD_INSECURE:-true} - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:${TRAEFIK_WEB_PORT:-8080} ports: - "${TRAEFIK_WEB_PORT:-8080}:${TRAEFIK_WEB_PORT:-8080}" - "${TRAEFIK_DASHBOARD_PORT:-8081}:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro networks: - edge - app postgres: image: postgres:16 environment: POSTGRES_DB: ${POSTGRES_DB:-multimailer} POSTGRES_USER: ${POSTGRES_USER:-multimailer} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-multimailer} volumes: - postgres_data:/var/lib/postgresql/data networks: - app healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-multimailer} -d ${POSTGRES_DB:-multimailer}"] interval: 10s timeout: 5s retries: 10 redis: image: redis:7-alpine command: ["redis-server", "--appendonly", "yes"] volumes: - redis_data:/data networks: - app healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 10 garage: image: dxflrs/garage:v2.3.0 command: ["garage", "-c", "/etc/garage.toml", "server", "--single-node", "--default-bucket"] environment: GARAGE_DEFAULT_ACCESS_KEY: ${S3_ACCESS_KEY_ID:-GKmultimailerdev0000000000000000} GARAGE_DEFAULT_SECRET_KEY: ${S3_SECRET_ACCESS_KEY:-multimailer-dev-secret-change-me} GARAGE_DEFAULT_BUCKET: ${S3_BUCKET:-attachments} ports: - "${GARAGE_S3_PORT:-3900}:3900" - "${GARAGE_ADMIN_PORT:-3903}:3903" volumes: - ./infra/garage/garage.toml:/etc/garage.toml:ro - garage_meta:/var/lib/garage/meta - garage_data:/var/lib/garage/data networks: - app networks: edge: name: ${COMPOSE_PROJECT_NAME:-multimailer}_edge volumes: postgres_data: redis_data: garage_meta: garage_data: