139 lines
5 KiB
YAML
139 lines
5 KiB
YAML
|
|
# =============================================================================
|
||
|
|
# 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
|