video-surveillance-app/docker-compose.yml

139 lines
5 KiB
YAML
Raw Normal View History

# =============================================================================
# iot-alarm-system
#
# Deux reseaux :
# - "default" : prive, Kafka et PostgreSQL n'y sont joignables que par l'app.
# Aucun port n'est publie sur l'hote - le broker n'est pas expose a Internet.
# - "edge" : reseau externe partage, ou le reverse proxy Caddy du serveur
# vient chercher l'application pour la servir en HTTPS.
#
# Note sur Zookeeper : absent volontairement. Kafka tourne en mode KRaft, son
# quorum interne. Zookeeper est deprecie depuis Kafka 3.5 et supprime en 4.0 ;
# le garder ajouterait un conteneur, ~400 Mo de RAM et une piece a maintenir.
# =============================================================================
services:
# ---------------------------------------------------------------------------
# Bus d'evenements - Kafka en KRaft mono-noeud
# ---------------------------------------------------------------------------
kafka:
image: apache/kafka:3.9.1
container_name: iot-alarm-kafka
restart: unless-stopped
environment:
CLUSTER_ID: "iot-alarm-cluster-0001"
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
# Mono-noeud : aucune replication possible, on l'assume explicitement.
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_LOG_RETENTION_HOURS: 72
KAFKA_LOG_DIRS: /var/lib/kafka/data
KAFKA_HEAP_OPTS: "-Xmx400m -Xms256m"
volumes:
- kafka_data:/var/lib/kafka/data
healthcheck:
test: ["CMD-SHELL", "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server localhost:9092 >/dev/null 2>&1"]
interval: 15s
timeout: 10s
retries: 12
start_period: 40s
mem_limit: 800m
networks: [default]
# ---------------------------------------------------------------------------
# Persistance - write model et read model
# ---------------------------------------------------------------------------
postgres:
image: postgres:16-alpine
container_name: iot-alarm-postgres
restart: unless-stopped
environment:
POSTGRES_DB: iotalarm
POSTGRES_USER: iotalarm
POSTGRES_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD est obligatoire, voir .env.example}
# Le checksum des pages detecte une corruption disque silencieuse.
POSTGRES_INITDB_ARGS: "--data-checksums"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U iotalarm -d iotalarm"]
interval: 10s
timeout: 5s
retries: 10
start_period: 15s
mem_limit: 256m
networks: [default]
# ---------------------------------------------------------------------------
# Application Spring Boot
# ---------------------------------------------------------------------------
app:
build:
context: .
dockerfile: Dockerfile
image: iot-alarm-system:1.0.0
container_name: iot-alarm-app
restart: unless-stopped
depends_on:
kafka:
condition: service_healthy
postgres:
condition: service_healthy
environment:
SPRING_PROFILES_ACTIVE: prod
KAFKA_BOOTSTRAP_SERVERS: kafka:9092
DB_URL: jdbc:postgresql://postgres:5432/iotalarm
DB_USERNAME: iotalarm
DB_PASSWORD: ${DB_PASSWORD}
SIMULATOR_ENABLED: ${SIMULATOR_ENABLED:-true}
SIMULATOR_INTERVAL: ${SIMULATOR_INTERVAL:-8s}
ALARM_EXIT_DELAY: ${ALARM_EXIT_DELAY:-30s}
ALARM_MIN_CONFIDENCE: ${ALARM_MIN_CONFIDENCE:-60}
LOG_LEVEL: ${LOG_LEVEL:-INFO}
mem_limit: 512m
# Joint les deux reseaux : "default" pour parler a Kafka et PostgreSQL,
# "edge" pour etre joignable par le reverse proxy.
networks: [default, edge]
# ---------------------------------------------------------------------------
# Nginx - profil "standalone" uniquement
#
# Sur le serveur de production, le frontal est le Caddy deja en place (il
# detient 80/443 et sert cinq autres domaines) : voir deploy/Caddyfile.snippet.
# Ce Nginx sert au cas "je clone le depot et je lance tout sur ma machine" :
# docker compose --profile standalone up -d -> http://localhost:8081
# ---------------------------------------------------------------------------
nginx:
image: nginx:alpine
container_name: iot-alarm-nginx
profiles: [standalone]
restart: unless-stopped
depends_on: [app]
ports:
- "8081:80"
volumes:
- ./deploy/nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
mem_limit: 64m
networks: [default]
volumes:
kafka_data:
postgres_data:
networks:
default:
name: iot-alarm-internal
edge:
external: true
name: edge