services: db: image: postgres:17 restart: unless-stopped healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 5 start_period: 20s volumes: - app-db-data:/var/lib/postgresql/data/pgdata env_file: - .env environment: PGDATA: /var/lib/postgresql/data/pgdata POSTGRES_PASSWORD: ${POSTGRES_PASSWORD?Variable not set} POSTGRES_USER: ${POSTGRES_USER?Variable not set} POSTGRES_DB: ${POSTGRES_DB?Variable not set} ports: - "5432:5432" mailcatcher: image: axllent/mailpit:latest restart: unless-stopped ports: - "1080:8025" - "1025:1025" adminer: image: adminer:latest restart: unless-stopped depends_on: db: condition: service_healthy ports: - "8080:8080" redis: image: redis:8-alpine restart: unless-stopped command: redis-server --save 60 1 --loglevel warning volumes: - app-redis-data:/data ports: - "6379:6379" prestart: build: context: . dockerfile: backend/Dockerfile args: BUILD_MANIFEST: artifacts/${APP_EDITION:-suite}/build-manifest.json depends_on: db: condition: service_healthy command: bash scripts/prestart.sh env_file: - .env environment: POSTGRES_SERVER: db APP_RUNTIME_DB_USER: ${APP_RUNTIME_DB_USER?Variable not set} APP_RUNTIME_DB_PASSWORD: ${APP_RUNTIME_DB_PASSWORD?Variable not set} REDIS_URL: ${REDIS_URL:-redis://redis:6379/0} APP_EDITION: ${APP_EDITION:-suite} backend: build: context: . dockerfile: backend/Dockerfile args: BUILD_MANIFEST: artifacts/${APP_EDITION:-suite}/build-manifest.json restart: unless-stopped depends_on: db: condition: service_healthy prestart: condition: service_completed_successfully env_file: - .env environment: POSTGRES_SERVER: db POSTGRES_USER: ${APP_RUNTIME_DB_USER?Variable not set} POSTGRES_PASSWORD: ${APP_RUNTIME_DB_PASSWORD?Variable not set} REDIS_URL: ${REDIS_URL:-redis://redis:6379/0} APP_EDITION: ${APP_EDITION:-suite} volumes: - app-uploads:/app/backend/uploads healthcheck: test: [ "CMD-SHELL", "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/api/v1/utils/health-check', timeout=5)\"", ] interval: 10s timeout: 5s retries: 5 ports: - "8000:8000" outbox-worker: build: context: . dockerfile: backend/Dockerfile args: BUILD_MANIFEST: artifacts/${APP_EDITION:-suite}/build-manifest.json restart: unless-stopped depends_on: db: condition: service_healthy prestart: condition: service_completed_successfully command: python -m app.modules.outbox_worker env_file: - .env environment: POSTGRES_SERVER: db POSTGRES_USER: ${APP_RUNTIME_DB_USER?Variable not set} POSTGRES_PASSWORD: ${APP_RUNTIME_DB_PASSWORD?Variable not set} REDIS_URL: ${REDIS_URL:-redis://redis:6379/0} APP_EDITION: ${APP_EDITION:-suite} schedule-worker: build: context: . dockerfile: backend/Dockerfile args: BUILD_MANIFEST: artifacts/${APP_EDITION:-suite}/build-manifest.json restart: unless-stopped depends_on: db: condition: service_healthy prestart: condition: service_completed_successfully command: python -m app.modules.schedule_worker env_file: - .env environment: POSTGRES_SERVER: db POSTGRES_USER: ${APP_RUNTIME_DB_USER?Variable not set} POSTGRES_PASSWORD: ${APP_RUNTIME_DB_PASSWORD?Variable not set} REDIS_URL: ${REDIS_URL:-redis://redis:6379/0} APP_EDITION: ${APP_EDITION:-suite} frontend: build: context: . dockerfile: frontend/Dockerfile args: VITE_GLOB_API_URL: /api/v1 restart: unless-stopped depends_on: backend: condition: service_healthy ports: - "5173:80" minio: image: minio/minio:latest profiles: ["storage"] restart: unless-stopped command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${S3_ACCESS_KEY_ID:-minioadmin} MINIO_ROOT_PASSWORD: ${S3_SECRET_ACCESS_KEY:-minioadmin} volumes: - app-minio-data:/data ports: - "9000:9000" - "9001:9001" volumes: app-db-data: app-redis-data: app-uploads: app-minio-data: