170 lines
5.3 KiB
YAML
170 lines
5.3 KiB
YAML
version: '3.8'
|
|
|
|
# Stack di produzione per la VPS, pensato per stare dietro a Caddy che gira
|
|
# su un CT Proxmox separato (routing per path sullo stesso dominio: "/" al
|
|
# frontend, "/api" al backend, "/auth" a Keycloak - vedi Caddyfile.example).
|
|
#
|
|
# Le variabili sono lette da un file ".env" nella stessa cartella
|
|
# (copia .env.example -> .env e compila i valori prima di avviare lo stack).
|
|
#
|
|
# Solo backend, frontend e keycloak pubblicano una porta sull'host (quella
|
|
# che deve raggiungere Caddy): postgres, mongodb e keycloak-db restano
|
|
# raggiungibili solo dalla rete Docker interna.
|
|
|
|
services:
|
|
# PostgreSQL Database (dati app)
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
container_name: scommetti-postgres
|
|
environment:
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
- ./backend-node/init.sql:/docker-entrypoint-initdb.d/init.sql
|
|
networks:
|
|
- scommetti-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
restart: unless-stopped
|
|
|
|
# MongoDB Database (bets)
|
|
mongodb:
|
|
image: mongo:7
|
|
container_name: scommetti-mongodb
|
|
environment:
|
|
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
|
|
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
|
|
MONGO_INITDB_DATABASE: ${MONGO_INITDB_DATABASE}
|
|
volumes:
|
|
- mongodb_data:/data/db
|
|
networks:
|
|
- scommetti-network
|
|
healthcheck:
|
|
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
restart: unless-stopped
|
|
|
|
# Keycloak Database
|
|
keycloak-db:
|
|
image: postgres:15-alpine
|
|
container_name: scommetti-keycloak-db
|
|
environment:
|
|
POSTGRES_DB: ${KEYCLOAK_DB}
|
|
POSTGRES_USER: ${KEYCLOAK_DB_USER}
|
|
POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
|
|
volumes:
|
|
- keycloak_db_data:/var/lib/postgresql/data
|
|
networks:
|
|
- scommetti-network
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${KEYCLOAK_DB_USER} -d ${KEYCLOAK_DB}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
restart: unless-stopped
|
|
|
|
# Keycloak Auth Server
|
|
keycloak:
|
|
image: quay.io/keycloak/keycloak:23.0.0
|
|
container_name: scommetti-keycloak
|
|
command: start --import-realm
|
|
environment:
|
|
KC_DB: postgres
|
|
KC_DB_URL: jdbc:postgresql://keycloak-db:5432/${KEYCLOAK_DB}
|
|
KC_DB_USERNAME: ${KEYCLOAK_DB_USER}
|
|
KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD}
|
|
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN}
|
|
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
|
|
KC_HEALTH_ENABLED: "true"
|
|
KC_METRICS_ENABLED: "true"
|
|
KC_HTTP_ENABLED: "true"
|
|
# Keycloak è raggiunto tramite Caddy su https://${DOMAIN}/auth/*: gli
|
|
# diciamo di servire tutto sotto /auth e di fidarsi degli header
|
|
# X-Forwarded-* impostati dal proxy (TLS termina su Caddy, "edge").
|
|
KC_HTTP_RELATIVE_PATH: /auth
|
|
KC_HOSTNAME: ${DOMAIN}
|
|
KC_HOSTNAME_PATH: /auth
|
|
KC_HOSTNAME_STRICT: "true"
|
|
KC_HOSTNAME_STRICT_HTTPS: "true"
|
|
KC_PROXY: edge
|
|
ports:
|
|
- "${BIND_IP}:${KEYCLOAK_PORT}:8080"
|
|
volumes:
|
|
- ./keycloak/realm-export.json:/opt/keycloak/data/import/realm.json:ro
|
|
- ./keycloak/themes/scommettiapp:/opt/keycloak/themes/scommettiapp:ro
|
|
depends_on:
|
|
keycloak-db:
|
|
condition: service_healthy
|
|
networks:
|
|
- scommetti-network
|
|
healthcheck:
|
|
# Con KC_HTTP_RELATIVE_PATH=/auth l'health endpoint si sposta sotto
|
|
# /auth/health/ready (verificato: /health/ready da solo risponde 404).
|
|
test: ["CMD-SHELL", "exec 3<>/dev/tcp/localhost/8080 && printf 'GET /auth/health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && timeout 5 cat <&3 | grep -q 'UP'"]
|
|
interval: 15s
|
|
timeout: 15s
|
|
retries: 10
|
|
start_period: 90s
|
|
restart: unless-stopped
|
|
|
|
# Backend Node.js
|
|
backend:
|
|
build:
|
|
context: ./backend-node
|
|
dockerfile: Dockerfile
|
|
target: production
|
|
container_name: scommetti-backend
|
|
environment:
|
|
NODE_ENV: ${NODE_ENV}
|
|
PORT: 3000
|
|
POSTGRES_URI: postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
|
|
MONGO_URI: mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongodb:27017/${MONGO_INITDB_DATABASE}?authSource=admin
|
|
KEYCLOAK_JWKS_URI: http://keycloak:8080/auth/realms/scommettiapp/protocol/openid-connect/certs
|
|
ports:
|
|
- "${BIND_IP}:${BACKEND_PORT}:3000"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
mongodb:
|
|
condition: service_healthy
|
|
keycloak:
|
|
condition: service_healthy
|
|
networks:
|
|
- scommetti-network
|
|
restart: unless-stopped
|
|
|
|
# Frontend Angular (build statica servita da nginx)
|
|
frontend:
|
|
build:
|
|
context: ./frontend-angular
|
|
dockerfile: Dockerfile
|
|
target: production
|
|
container_name: scommetti-frontend
|
|
ports:
|
|
- "${BIND_IP}:${FRONTEND_PORT}:80"
|
|
depends_on:
|
|
- backend
|
|
- keycloak
|
|
networks:
|
|
- scommetti-network
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
postgres_data:
|
|
driver: local
|
|
mongodb_data:
|
|
driver: local
|
|
keycloak_db_data:
|
|
driver: local
|
|
|
|
networks:
|
|
scommetti-network:
|
|
driver: bridge
|