Files
PecHub/docker-compose.prod.yml
T
2026-06-18 15:14:10 +02:00

204 lines
7.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: pechub
# ─────────────────────────────────────────────────────────────────────────────
# docker-compose.prod.yml Configurazione PRODUZIONE
#
# Differenze rispetto a docker-compose.yml (sviluppo):
# - Backend: uvicorn con N worker, senza --reload, senza volume mount
# - Frontend: build statica servita da nginx (niente Vite dev server)
# - Porte DB, Redis, MinIO NON esposte sull'host (solo rete interna)
# - Tutte le credenziali lette da .env (obbligatorie)
# - MinIO console disabilitata (porta 9001 non esposta)
# - GreenMail e pgadmin esclusi
# - Healthcheck ottimizzati per produzione
#
# Utilizzo:
# docker compose -f docker-compose.prod.yml up -d
# ─────────────────────────────────────────────────────────────────────────────
services:
# ─── PostgreSQL 16 ──────────────────────────────────────────────────────────
db:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_DB: ${POSTGRES_DB:-pechub}
POSTGRES_USER: ${POSTGRES_USER:-pechub}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD non impostata}
# PRODUZIONE: porte DB non esposte sull'host
volumes:
- postgres_data:/var/lib/postgresql/data
- ./database/init:/docker-entrypoint-initdb.d/init:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-pechub} -d ${POSTGRES_DB:-pechub}"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
networks:
- pechub_net
# ─── Redis 7 ────────────────────────────────────────────────────────────────
redis:
image: redis:7-alpine
restart: always
command: redis-server /usr/local/etc/redis/redis.conf
# PRODUZIONE: porta Redis non esposta sull'host
volumes:
- redis_data:/data
- ./infra/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 10
start_period: 10s
networks:
- pechub_net
# ─── MinIO (Object Storage S3-compatible) ───────────────────────────────────
minio:
image: minio/minio:latest
restart: always
# PRODUZIONE: solo API S3 (9000), console (9001) non esposta
command: server /data
environment:
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY non impostata}
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?MINIO_SECRET_KEY non impostata}
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 15s
timeout: 5s
retries: 5
start_period: 20s
networks:
- pechub_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 ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY} &&
mc mb --ignore-existing local/${MINIO_BUCKET:-pechub} &&
mc anonymous set none local/${MINIO_BUCKET:-pechub} &&
echo 'MinIO bucket creato'
"
networks:
- pechub_net
# ─── Backend FastAPI (produzione) ────────────────────────────────────────────
backend:
build:
context: ./backend
dockerfile: Dockerfile
restart: always
env_file: .env
environment:
APP_ENV: production
APP_DEBUG: "false"
LOG_JSON: "true"
DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-pechub}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-pechub}
DATABASE_URL_SYNC: postgresql://${POSTGRES_USER:-pechub}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-pechub}
REDIS_URL: redis://redis:6379/0
MINIO_ENDPOINT: minio:9000
# PRODUZIONE: N worker, senza --reload, senza volume mount del codice
command: >
uvicorn app.main:app
--host 0.0.0.0
--port 8000
--workers 4
--loop uvloop
--http httptools
--access-log
--log-level warning
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 15s
timeout: 5s
retries: 5
start_period: 30s
networks:
- pechub_net
# ─── Frontend React (build statica servita da nginx) ─────────────────────────
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
target: runner # stage nginx con build statica (dist/)
restart: always
expose:
- "3000"
depends_on:
- backend
networks:
- pechub_net
# ─── Nginx reverse proxy (produzione) ────────────────────────────────────────
nginx:
image: nginx:alpine
restart: always
ports:
- "80:80"
# Per HTTPS: decommentare e configurare certificati
# - "443:443"
volumes:
- ./infra/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./infra/nginx/conf.d/pecflow.prod.conf:/etc/nginx/conf.d/default.conf:ro
# Per HTTPS: montare i certificati
# - /etc/letsencrypt:/etc/letsencrypt:ro
depends_on:
backend:
condition: service_healthy
frontend:
condition: service_started
networks:
- pechub_net
# ─── Worker IMAP Sync (arq) ──────────────────────────────────────────────────
worker:
build:
context: ./worker
dockerfile: Dockerfile
restart: always
env_file: .env
environment:
APP_ENV: production
LOG_LEVEL: WARNING
DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-pechub}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB:-pechub}
REDIS_URL: redis://redis:6379/0
MINIO_ENDPOINT: minio:9000
# PRODUZIONE: niente volume mount del codice
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_healthy
networks:
- pechub_net
volumes:
postgres_data:
redis_data:
minio_data:
networks:
pechub_net:
driver: bridge