services: # ---------------------------------------------------------------------- # Proxy inverse # # ---------------------------------------------------------------------- # Caddy # Web server, load balancer, and reverse proxy # https://caddyserver.com/ caddy: image: lucaslorentz/caddy-docker-proxy:2.10 restart: "no" ports: - "80:80" - "443:443/tcp" - "443:443/udp" networks: - caddy_net environment: CADDY_INGRESS_NETWORKS: ${COMPOSE_PROJECT_NAME}_caddy_net volumes: - caddy_config:/config - caddy_data:/data - /var/run/docker.sock:/var/run/docker.sock:ro - ./data:/srv/www:ro labels: caddy: localhost caddy.root: "* /srv/www" caddy.file_server: "" # Active le serveur de fichiers statiques caddy.tls: internal # HTTPS auto-signé géré par Caddy # WhoAmI # Tiny Go webserver that prints OS information and HTTP request to output. # https://github.com/traefik/whoami whoami: image: traefik/whoami depends_on: - caddy networks: - caddy_net labels: caddy: whoami.localhost caddy.reverse_proxy: "{{upstreams 80}}" caddy.tls: internal # ---------------------------------------------------------------------- # Base de données relationnelles # # ---------------------------------------------------------------------- database: image: iut/pgsql:2025-12 environment: POSTGRES_INITDB_ARGS: "--locale-provider=icu --icu-locale=fr-FR" POSTGRES_PASSWORD: ${PG_PASSWORD:-!ChangeMe!} POSTGRES_USER: ${COMPOSE_PROJECT_NAME} volumes: - database_data:/var/lib/postgresql:rw - ./postgresql-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z - ./data:/tmp:z ports: - "5432:5432" networks: - caddy_net healthcheck: test: ["CMD", "pg_isready", "--username", "${COMPOSE_PROJECT_NAME}", "--dbname", "${COMPOSE_PROJECT_NAME}"] interval: 10s timeout: 5s retries: 5 start_period: 20s # ---------------------------------------------------------------------- # Administration # # ---------------------------------------------------------------------- # pgAdmin # Rich administration and development platform for PostgreSQL. # https://www.pgadmin.org/ pgadmin: image: dpage/pgadmin4:9.8 depends_on: database: condition: service_healthy caddy: condition: service_started restart: "no" configs: - source: pgadmin_config target: /pgadmin4/servers.json volumes: - pgadmin:/var/lib/pgadmin/ environment: PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL} PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD} PGADMIN_DISABLE_POSTFIX: true networks: - caddy_net labels: caddy: pgadmin.localhost caddy.reverse_proxy: "{{upstreams 80}}" caddy.tls: internal # ---------------------------------------------------------------------- # Documents # # ---------------------------------------------------------------------- # CouchDB # Single-node document database # https://couchdb.apache.org/ couchdb: image: couchdb:3.5 volumes: - couchdb_data:/opt/couchdb/data environment: COUCHDB_USER: ${COUCHDB_USER} COUCHDB_PASSWORD: ${COUCHDB_PASSWORD} ports: - 5984:5984 networks: - caddy_net labels: caddy: couchdb.localhost caddy.reverse_proxy: "{{upstreams 5984}}" caddy.tls: internal couchdb-init: build: dockerfile: ./couchdb-init.Dockerfile context: . environment: COUCHDB_USER: ${COUCHDB_USER} COUCHDB_PASSWORD: ${COUCHDB_PASSWORD} depends_on: - couchdb networks: - caddy_net # MongoDB # # https://www.mongodb.com/ mongodb: image: mongodb/mongodb-community-server:8.0-ubi8 volumes: - mongodb_configdb:/data/configdb - mongodb_data:/data/db - ./mongodb-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z - ./data:/initdb.d:z ports: - "27017:27017" networks: - caddy_net environment: MONGODB_INITDB_ROOT_USERNAME: ${MONGODB_USER} MONGODB_INITDB_ROOT_PASSWORD: ${MONGODB_PASSWORD} mongo-express: image: mongo-express restart: "no" depends_on: - mongodb environment: ME_CONFIG_MONGODB_URL: mongodb://${MONGODB_USER}:${MONGODB_PASSWORD}@mongodb:27017/ ME_CONFIG_BASICAUTH_ENABLED: true ME_CONFIG_BASICAUTH_USERNAME: mongoexpressuser ME_CONFIG_BASICAUTH_PASSWORD: mongoexpresspass networks: - caddy_net labels: caddy: mongo-express.localhost caddy.reverse_proxy: "{{upstreams 8081}}" caddy.tls: internal # Redis # In-memory key-value database # https://redis.io/fr/ redis: image: redis:8.2 command: - 'redis-server' - '--save 60 1' - '--loglevel verbose' - '--requirepass ${REDIS_PASSWORD}' ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "--raw", "incr", "ping" ] interval: 30s timeout: 5s retries: 3 start_period: 20s volumes: - redis_data:/data # Neo4J # Des graphes ultra-rapides, à l’échelle du pétaoctet # https://neo4j.com/ neo4j: image: neo4j:5.26.12-community ports: - 7474:7474 - 7687:7687 volumes: - neo4j_data:/data - neo4j_logs:/logs environment: NEO4J_dbms_connector_https_enabled: "false" NEO4J_AUTH: neo4j/${NEO4J_PASSWORD:-!ChangeMe!} networks: - caddy_net labels: caddy: neo4j.localhost caddy.reverse_proxy: "{{upstreams 7474}}" caddy.tls: internal # PostGraphile # Instant GraphQL API # https://www.graphile.org/postgraphile/ postgraphile: image: iut/postgraphile:2025-12 restart: "no" depends_on: database: condition: service_healthy command: [ "--port", "80", "--schema", "${POSTGRAPHILE_SCHEMA:-public}", "--enhance-graphiql", "--cors", "--allow-explain", "--dynamic-json", "--append-plugins", "postgraphile-plugin-connection-filter,postgraphile-plugin-fulltext-filter,@graphile/postgis,postgraphile-plugin-connection-filter-postgis" ] networks: - caddy_net environment: - PGHOST=database - PGPORT=5432 - PGUSER=${POSTGRAPHILE_USER:-postgraphile_user} - PGPASSWORD=${POSTGRAPHILE_PASSWORD:-9013} - PGDATABASE=${COMPOSE_PROJECT_NAME} labels: caddy: postgraphile.localhost caddy.reverse_proxy: "{{upstreams 80}}" caddy.tls: internal # ---------------------------------------------------------------------- # Web API # # ---------------------------------------------------------------------- # PostgREST # Serve a fully RESTful API from any existing PostgreSQL database. # It provides a cleaner, more standards-compliant, faster API than you are likely to write from scratch. # https://docs.postgrest.org/en/v13/ postgrest: image: postgrest/postgrest:v13.0.7 restart: "no" depends_on: database: condition: service_healthy caddy: condition: service_started command: postgrest environment: PGRST_DB_URI: postgres://${POSTGREST_USER:-postgrest}:${POSTGREST_PASSWORD}@${POSTGREST_HOST:-database}:${POSTGREST_DB_PORT:-5432}/${COMPOSE_PROJECT_NAME} PGRST_DB_SCHEMAS: ${POSTGREST_DB_SCHEMAS:-public} PGRST_DB_ANON_ROLE: ${POSTGREST_DB_ANON_ROLE:-anonyme} PGRST_JWT_SECRET: ${POSTGREST_JWT_SECRET:-ChangeMeChangeMeChangeMeChangeMe} PGRST_ADMIN_SERVER_PORT: 3055 PGRST_SERVER_PORT: 80 PGRST_OPENAPI_SERVER_PROXY_URI: https://postgrest.localhost networks: - caddy_net labels: caddy: postgrest.localhost caddy.reverse_proxy: "{{upstreams 80}}" caddy.tls: internal # Scalar # Create world-class API Docs with a built-in interactive playground # which seamlessly turns to a full featured API Client scalar: image: scalarapi/api-reference:0.4.2 restart: "no" environment: API_REFERENCE_CONFIG: | { "sources":[ { "url": "https://postgrest.localhost" } ], "theme": "purple" } networks: - caddy_net labels: caddy: scalar.localhost caddy.reverse_proxy: "{{upstreams 8080}}" caddy.tls: internal # ---------------------------------------------------------------------- # Mock Web API # # ---------------------------------------------------------------------- smocker: image: thiht/smocker:0.18.5 restart: "no" networks: - caddy_net ports: - 8080:8080 - 8081:8081 toxiproxy: image: ghcr.io/shopify/toxiproxy restart: "no" # ---------------------------------------------------------------------- # Business Intelligence # # ---------------------------------------------------------------------- superset: image: apache/superset:3.1.3 depends_on: database: condition: service_healthy environment: SUPERSET_CONFIG_PATH: /app/pythonpath/superset_config.py SUPERSET_SECRET_KEY: ${SUPERSET_SECRET:-YOUR_OWN_RANDOM_GENERATED_SECRET_KEY} SUPERSET_LOAD_EXAMPLES: no volumes: - superset_home:/app/superset_home - ./superset_config.py:/app/pythonpath/superset_config.py:Z command: > sh -c " superset db upgrade && superset fab create-admin --username admin --firstname Admin --lastname User --email admin@superset.com --password admin && superset init && superset run -h 0.0.0.0 -p 80 --with-threads --reload --debugger " networks: - caddy_net labels: caddy: superset.localhost caddy.reverse_proxy: "{{upstreams 80}}" caddy.tls: internal metabase: image: metabase/metabase:v0.56.5.5 depends_on: database: condition: service_healthy volumes: - /dev/urandom:/dev/random:ro environment: MB_DB_TYPE: postgres MB_DB_HOST: ${MB_DB_HOST:-database} MB_DB_PORT: 5432 MB_DB_USER: metabase_user MB_DB_PASS: ${DB_ROOT_PASSWORD:-supermotdepasse} MB_DB_DBNAME: metabase MB_SITE_LOCALE: fr MB_ADMIN_EMAIL: etudiant@univ-lorraine.fr MB_ANON_TRACKING_ENABLED: false MB_CHECK_FOR_UPDATES: false MB_NO_SURVEYS: yes MB_START_OF_WEEK: monday MB_CUSTOM_FORMATTING: '{"type/Temporal":{"time_style":"HH:mm","date_style":"D MMMM, YYYY","date_abbreviate":true},"type/Currency":{"currency":"EUR"},"type/Number":{"number_separators":", "}}' MB_EMAIL_SMTP_HOST: mailpit MB_EMAIL_SMTP_PORT: 1025 MB_EMAIL_FROM_ADDRESS: metabase@univ-lorraine.fr networks: - caddy_net labels: caddy: metabase.localhost caddy.reverse_proxy: "{{upstreams 3000}}" caddy.tls: internal metabase-init: build: context: ./metabase depends_on: - metabase networks: - caddy_net rabbitmq: image: rabbitmq:4.1.4-management ports: - "5672:5672" # AMQP - "1883:1883" # MQTT networks: - caddy_net environment: RABBITMQ_DEFAULT_USER: admin RABBITMQ_DEFAULT_PASS: admin RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS: "-rabbitmq_mqtt tcp_listeners [1883]" volumes: - rabbitmq_data:/var/lib/rabbitmq command: > sh -c "rabbitmq-plugins enable --offline rabbitmq_mqtt rabbitmq_management && rabbitmq-server" labels: caddy: rabbitmq.localhost caddy.reverse_proxy: "{{upstreams 15672}}" caddy.tls: internal # ---------------------------------------------------------------------- # Observabilité - Télémétrie # # ---------------------------------------------------------------------- # Grafana # Open source analytics & monitoring solution for every database. # https://grafana.com/ grafana: image: grafana/grafana-oss:12.1.0 restart: no deploy: resources: limits: memory: 100M configs: - source: grafana_provisioning target: /etc/grafana/provisioning - source: grafana_dashboards target: /etc/grafana/dashboards volumes: - grafana:/var/lib/grafana environment: #GF_SECURITY_ADMIN_EMAIL: ${ADMIN_EMAIL} #GF_SECURITY_ADMIN_PASSWORD: ${ADMIN_PASSWORD} GF_AUTH_ANONYMOUS_ENABLED: true # Enabled the Anonymous user no user/pass needed GF_AUTH_ANONYMOUS_ORG_ROLE: Admin GF_AUTH_DISABLE_LOGIN_FORM: true GF_USERS_DEFAULT_THEME: light GF_USERS_ALLOW_SIGN_UP: false GF_FEATURE_TOGGLES_ENABLE: traceQLStreaming metricsSummary lokiFormatQuery alertmanagerRemoteOnly GF_INSTALL_PLUGINS: yesoreyeram-infinity-datasource networks: - caddy_net labels: caddy: grafana.localhost caddy.reverse_proxy: "{{upstreams 3000}}" caddy.tls: internal # Prometheus # Prometheus is an open-source systems monitoring and alerting toolkit # https://prometheus.io/ prometheus: image: prom/prometheus:v3.6.0 configs: - source: prometheus_config target: /etc/prometheus/prometheus.yml volumes: - prometheus:/prometheus - /var/run/docker.sock:/var/run/docker.sock:ro ports: - 9090:9090 #extra_hosts: # - host.docker.internal=host-gateway gatus: image: twinproduction/gatus:v5.26.0 ports: - 8080:8080 mailpit: image: axllent/mailpit:v1.27 restart: "no" ports: - "8025:8025" - "1025:1025" environment: TZ: Europe/Paris volumes: - mailpit:/data volumes: caddy_config: caddy_data: pgadmin: database_data: couchdb_data: mongodb_data: mongodb_configdb: redis_data: neo4j_data: neo4j_logs: prometheus: grafana: superset_home: rabbitmq_data: mailpit: configs: pgadmin_config: file: ./pgadmin-servers.json grafana_provisioning: file: ./grafana/provisioning grafana_dashboards: file: ./grafana/dashboards prometheus_config: file: ./prometheus.yml networks: caddy_net: driver: bridge