name: pecflow services: # ─── PostgreSQL 16 ────────────────────────────────────────────────────────── db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: pecflow POSTGRES_USER: pecflow POSTGRES_PASSWORD: pecflow_dev_password ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./database/init:/docker-entrypoint-initdb.d/init:ro - ./database/seeds:/docker-entrypoint-initdb.d/seeds:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U pecflow -d pecflow"] interval: 5s timeout: 5s retries: 10 networks: - pecflow_net # ─── Redis 7 ──────────────────────────────────────────────────────────────── redis: image: redis:7-alpine restart: unless-stopped command: redis-server /usr/local/etc/redis/redis.conf ports: - "6379:6379" volumes: - redis_data:/data - ./infra/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 10 networks: - pecflow_net # ─── MinIO (Object Storage S3-compatible) ─────────────────────────────────── minio: image: minio/minio:latest restart: unless-stopped command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: minioadmin MINIO_ROOT_PASSWORD: minioadmin ports: - "9000:9000" # API S3 - "9001:9001" # Console web volumes: - minio_data:/data healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 10s timeout: 5s retries: 5 networks: - pecflow_net # ─── MinIO bucket initializer ─────────────────────────────────────────────── minio-init: image: minio/mc:latest depends_on: minio: condition: service_healthy entrypoint: > /bin/sh -c " mc alias set local http://minio:9000 minioadmin minioadmin && mc mb --ignore-existing local/pecflow && mc anonymous set none local/pecflow && echo 'MinIO bucket pecflow creato' " networks: - pecflow_net # ─── Backend FastAPI ───────────────────────────────────────────────────────── backend: build: context: ./backend dockerfile: Dockerfile restart: unless-stopped env_file: .env environment: DATABASE_URL: postgresql+asyncpg://pecflow:pecflow_dev_password@db:5432/pecflow DATABASE_URL_SYNC: postgresql://pecflow:pecflow_dev_password@db:5432/pecflow REDIS_URL: redis://redis:6379/0 MINIO_ENDPOINT: minio:9000 ports: - "8000:8000" volumes: - ./backend:/app # hot-reload in development depends_on: db: condition: service_healthy redis: condition: service_healthy command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 10s timeout: 5s retries: 5 networks: - pecflow_net # ─── Frontend React (Vite dev server) ────────────────────────────────────── frontend: build: context: ./frontend dockerfile: Dockerfile target: dev restart: unless-stopped # La porta 3000 è esposta solo internamente via Nginx (non mappata all'host) # per evitare conflitti. Accedi tramite http://localhost (porta 80) expose: - "3000" volumes: - ./frontend:/app - /app/node_modules # evita che il mount sovrascriva i node_modules del container environment: - NODE_ENV=development depends_on: - backend networks: - pecflow_net # ─── Nginx reverse proxy ───────────────────────────────────────────────────── nginx: image: nginx:alpine restart: unless-stopped ports: - "80:80" volumes: - ./infra/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./infra/nginx/conf.d:/etc/nginx/conf.d:ro depends_on: - backend - frontend networks: - pecflow_net # ─── Worker IMAP Sync (arq) ────────────────────────────────────────────────── worker: build: context: ./worker dockerfile: Dockerfile restart: unless-stopped env_file: .env environment: DATABASE_URL: postgresql+asyncpg://pecflow:pecflow_dev_password@db:5432/pecflow REDIS_URL: redis://redis:6379/0 MINIO_ENDPOINT: minio:9000 volumes: - ./worker:/worker # hot-reload in development depends_on: db: condition: service_healthy redis: condition: service_healthy minio: condition: service_healthy networks: - pecflow_net # ─── GreenMail (server IMAP/SMTP mock per test) ─────────────────────────────── greenmail: image: greenmail/standalone:2.1.2 restart: unless-stopped environment: # Crea utente di test: test@example.com / secret GREENMAIL_OPTS: > -Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled=false -Dgreenmail.users=test@example.com:secret -Dgreenmail.verbose=false ports: - "3025:3025" # SMTP - "3110:3110" # POP3 - "3143:3143" # IMAP - "3465:3465" # SMTPS - "3993:3993" # IMAPS - "8080:8080" # API REST GreenMail healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/api/service/readiness"] interval: 10s timeout: 5s retries: 5 profiles: - greenmail # avviato solo con: docker compose --profile greenmail up networks: - pecflow_net # ─── PgAdmin (solo dev) ────────────────────────────────────────────────────── pgadmin: image: dpage/pgadmin4:latest restart: unless-stopped environment: PGADMIN_DEFAULT_EMAIL: admin@pecflow.it PGADMIN_DEFAULT_PASSWORD: admin PGADMIN_CONFIG_SERVER_MODE: "False" ports: - "5050:80" volumes: - pgadmin_data:/var/lib/pgadmin depends_on: - db profiles: - tools networks: - pecflow_net volumes: postgres_data: redis_data: minio_data: pgadmin_data: networks: pecflow_net: driver: bridge