Ctrl K
ComunidadGuías…

docker-compose.prod.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Reference production compose stack for the EDR server + MySQL.
# Distinct from docker-compose.yml (dev MySQL only). Full setup +
# secret-file generation documented in docker-compose.prod.README.md.
# Boot shortcut:
#
#   docker compose -f docker-compose.prod.yml up -d
#
# The server image is pulled from ghcr.io/rawtrail/rawtrail-server; a local
# build uses the docker-compose.prod.build.yml override for smoke tests and
# air-gapped sites.

services:
  mysql:
    image: mysql:8.4.9@sha256:c36050afdca850f23cef85703f84c7531a5ae155a11b5ee1c60acb09937c4084
    restart: unless-stopped
    environment:
      # MySQL 8.4 reads these _FILE variants natively. Avoids root password in
      # any compose env block or docker inspect output.
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root
      MYSQL_DATABASE: edr
    volumes:
      - edr-mysql-data:/var/lib/mysql
    secrets:
      - mysql_root
    healthcheck:
      # --silent and redirecting stderr keeps healthcheck logs out of the main
      # service log. The 10s start_period lets InnoDB recover before we gate on
      # a successful ping.
      test: ["CMD-SHELL", "mysqladmin ping --silent 2>/dev/null || exit 1"]
      interval: 5s
      timeout: 5s
      retries: 20
      start_period: 10s

  # ClickHouse event archive (ADR-0015): the durable event store the server writes ingested events to and reads them back
  # from. Reachable only on the private compose network (no host port), same posture as mysql. The default user is
  # passwordless; the DSN rides a docker secret so a password can be added later without editing this file.
  clickhouse:
    image: clickhouse/clickhouse-server:24.8@sha256:1ffa82edee000a42c09313bd9f1293d94c570aee74babc1b3ca9983a35fa597b
    restart: unless-stopped
    environment:
      CLICKHOUSE_DB: edr
      # Required for the default user to authenticate over the network with an empty password; without it the server's
      # ClickHouse ping fails with code 516 (AUTHENTICATION_FAILED). Mirrors the dev/demo clickhouse service.
      CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: "1"
    ulimits:
      # ClickHouse opens many files; the stock 1024 soft limit trips "too many open files" under load.
      nofile:
        soft: 262144
        hard: 262144
    volumes:
      - edr-clickhouse-data:/var/lib/clickhouse
    healthcheck:
      test: ["CMD", "clickhouse-client", "--query", "SELECT 1"]
      interval: 5s
      timeout: 5s
      retries: 20
      start_period: 10s

  server:
    # Set EDR_VERSION in .env to pin a release tag (recommended). `latest` is
    # fine for dev but unsafe for production because image digests can drift.
    # For a local source build instead of a pull, layer the build override:
    #   docker compose -f docker-compose.prod.yml -f docker-compose.prod.build.yml up -d --build
    image: ghcr.io/rawtrail/rawtrail-server:${EDR_VERSION:-latest}
    restart: unless-stopped
    # Longer than every stage of a graceful stop put together: the drain (EDR_SHUTDOWN_DRAIN,
    # 30s), the in-flight deadline (15s), the two loop joins (10s + 5s) and the telemetry
    # flush (5s): 65s in all. Docker's default is 10s, which cuts the drain the load
    # balancer is watching and severs in-flight requests (#1127). test/arch keeps this
    # in step with those five constants. Raise it too if you raise EDR_SHUTDOWN_DRAIN.
    stop_grace_period: 90s
    depends_on:
      mysql:
        condition: service_healthy
      clickhouse:
        condition: service_healthy
    environment:
      # The MySQL DSN needs the runtime root password that MYSQL reads from
      # the same secret file. We consume it via *_FILE (see server/config/
      # file_env.go) rather than interpolating so the password never lands in
      # `docker inspect` output. The env key is blank here so the *_FILE path
      # wins unconditionally; the server's fileBackedGetenv wrapper does the
      # rest.
      EDR_DSN: ""
      EDR_DSN_FILE: /run/secrets/edr_dsn
      EDR_ENROLL_SECRET_FILE: /run/secrets/enroll_secret
      # Deployment root secret (>=32 bytes). Required unconditionally: the
      # host-token HMAC pepper and other long-lived keys derive from it via HKDF
      # (server/config/config.go loadSecretKey), so the server refuses to boot
      # without it. Read from a docker-secret file so it never lands in
      # `docker inspect`. Changing it invalidates every enrolled host.
      EDR_SECRET_KEY_FILE: /run/secrets/secret_key
      # ClickHouse event archive DSN (ADR-0015), the event store the server refuses to boot without. Passwordless on the
      # private network; blank env so the *_FILE path wins and no value lands in `docker inspect`.
      EDR_CLICKHOUSE_DSN: ""
      EDR_CLICKHOUSE_DSN_FILE: /run/secrets/clickhouse_dsn
      # TLS cert paths are required unless EDR_TLS_TERMINATED_BY_PROXY=1 says a
      # proxy in front terminates TLS. Mount fullchain.pem + privkey.pem under
      # ./tls/ (or override EDR_TLS_DIR to point at your cert store). The server
      # refuses to boot when either path is empty or unreadable.
      EDR_TLS_CERT_FILE: ${EDR_TLS_CERT_FILE:-/tls/fullchain.pem}
      EDR_TLS_KEY_FILE: ${EDR_TLS_KEY_FILE:-/tls/privkey.pem}
      EDR_LOG_LEVEL: ${EDR_LOG_LEVEL:-info}
      EDR_LOG_FORMAT: "json"
      OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-}
      OTEL_SERVICE_NAME: rawtrail-server
    volumes:
      # Optional: mount a tls dir if fullchain.pem + privkey.pem exist. The
      # `:ro` flag + `tls:` default-empty env makes this safe when unused.
      - ${EDR_TLS_DIR:-./tls}:/tls:ro
    secrets:
      - enroll_secret
      - edr_dsn
      - secret_key
      - clickhouse_dsn
    ports:
      - "${EDR_LISTEN:-8088}:8088"
    # No server-side HEALTHCHECK: the distroless/static base has no shell
    # and no wget/curl, so `CMD-SHELL` healthchecks always fail. Nothing
    # depends_on the server here, so operator-side readiness checks
    # (curl http(s)://host:${EDR_LISTEN}/readyz) are the canonical path.
    # If we ever need container-level health, compile a tiny static
    # healthcheck binary into the image and invoke it via
    # `HEALTHCHECK ["CMD", "/usr/local/bin/healthcheck"]` (no shell).

volumes:
  edr-mysql-data:
  edr-clickhouse-data:

secrets:
  mysql_root:
    file: ./secrets/mysql_root
  enroll_secret:
    file: ./secrets/enroll_secret
  # edr_dsn is derived from mysql_root at `docker compose up` time via a
  # compose-secret hack: the operator writes it once. See README.
  edr_dsn:
    file: ./secrets/edr_dsn
  secret_key:
    file: ./secrets/secret_key
  # Fixed passwordless DSN pointing at the clickhouse service on the private
  # network. In a secret file for parity with edr_dsn (a ClickHouse password,
  # if added, would live here). See README.
  clickhouse_dsn:
    file: ./secrets/clickhouse_dsn