docker-compose.quickstart.yml
Rama main · réplica de lectura del repositorio original.
# Single-VM getting-started stack: MySQL + the EDR server + Caddy.
#
# Caddy terminates public HTTPS with automatic Let's Encrypt certificates and
# reverse-proxies to the server over the private Docker network, so the operator
# manages zero certificates and there is NO content-inspecting WAF in the path
# (unlike a managed PaaS edge). Bring it up with ./bootstrap.sh, which generates
# the secret files and .env this stack expects. Full walkthrough:
# docs/quickstart-vm.md. For high availability, use
# packaging/docker-compose-multi-replica.yml instead.
services:
mysql:
image: mysql:8.4.9@sha256:c36050afdca850f23cef85703f84c7531a5ae155a11b5ee1c60acb09937c4084
restart: unless-stopped
# Single MySQL instance: no replica and no point-in-time recovery, so the
# binary log is pure overhead. Disabling it drops a per-commit fsync and
# roughly halves write volume, which directly relieves the disk-bound event
# store. The buffer pool is MySQL's page cache: at MySQL's own 128 MB default
# the session views read most pages from disk, so it defaults to 1 GB here
# and EDR_MYSQL_BUFFER_POOL_SIZE in .env resizes it. The other ingest knobs
# (commit durability, flush pacing) are disk-specific, so they are not
# defaulted; see "Tuning MySQL" in docs/quickstart-vm.md.
command:
- --skip-log-bin
- --innodb-buffer-pool-size=${EDR_MYSQL_BUFFER_POOL_SIZE:-1G}
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mysql_root
MYSQL_DATABASE: edr
volumes:
- edr-mysql-data:/var/lib/mysql
secrets:
- mysql_root
healthcheck:
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:
# Pin EDR_VERSION in .env to a release tag for production; bootstrap.sh warns
# when it defaults to `latest`.
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
# Pass .env through to the server so any server variable (OIDC/SSO, session
# timeouts, JIT provisioning, etc.) can be set there without editing this
# file. The explicit `environment:` keys below take precedence over .env, so
# the security-critical wiring (proxy-terminated TLS, trusted proxies, the
# secret *_FILE paths) cannot be overridden by accident. See
# docs/quickstart-vm.md ("Set server configuration").
env_file:
- .env
environment:
# DSN + secrets are read from files (docker secrets) so no password lands
# in `docker inspect`. EDR_DSN is blank so the *_FILE path wins.
EDR_DSN: ""
EDR_DSN_FILE: /run/secrets/edr_dsn
EDR_ENROLL_SECRET_FILE: /run/secrets/enroll_secret
EDR_SECRET_KEY_FILE: /run/secrets/secret_key
# ClickHouse event archive DSN (ADR-0015). Passwordless on the private network; blank env so the *_FILE path wins.
EDR_CLICKHOUSE_DSN: ""
EDR_CLICKHOUSE_DSN_FILE: /run/secrets/clickhouse_dsn
# Caddy terminates TLS in front; the server listens plaintext on the
# private Docker network only. It is never published to the host, so the
# only way in is through Caddy.
EDR_LISTEN_ADDR: "0.0.0.0:8088"
EDR_TLS_TERMINATED_BY_PROXY: "1"
# Trust X-Forwarded-For only from the Docker bridge network (Caddy). The
# default Compose address pool lives inside 172.16.0.0/12.
EDR_TRUSTED_PROXIES: "172.16.0.0/12"
# Break-glass WebAuthn binds credentials to the public host, so both must
# equal your domain.
EDR_BREAKGLASS_RP_ID: ${EDR_DOMAIN}
EDR_BREAKGLASS_RP_ORIGINS: https://${EDR_DOMAIN}
# Sign in with the break-glass admin, then configure SSO under Admin
# settings -> Single sign-on; it applies at runtime and survives restarts.
# See docs/quickstart-vm.md ("Single sign-on (OIDC)"). The server always
# boots without OIDC config (issue #512).
EDR_LOG_LEVEL: ${EDR_LOG_LEVEL:-info}
EDR_LOG_FORMAT: "json"
# Process-graph retention: completed process records older than this are
# deleted from MySQL, except those an alert references. Events live in
# ClickHouse and expire on their own 30-day window, so this matches it: a
# shorter value leaves every older alert's graph showing its process with
# none of its neighbours while the event timeline is complete. Lower it in
# .env if MySQL disk is tight.
EDR_RETENTION_DAYS: ${EDR_RETENTION_DAYS:-30}
# OTel export (optional). Set OTEL_EXPORTER_OTLP_ENDPOINT in .env to an
# OTLP/gRPC collector to turn on traces, metrics, and logs; leave it unset
# to keep telemetry off. The URL scheme picks the transport: http:// is
# plaintext, https:// uses TLS. OTEL_EXPORTER_OTLP_HEADERS carries an
# auth/ingestion token (e.g. SigNoz Cloud); OTEL_RESOURCE_ATTRIBUTES sets
# deployment.environment and any other resource tags.
# OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta suits SigNoz and
# Datadog; leave it unset (cumulative) for Prometheus-style backends. See
# docs/quickstart-vm.md ("Send telemetry to a collector").
OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-}
OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-}
OTEL_EXPORTER_OTLP_COMPRESSION: ${OTEL_EXPORTER_OTLP_COMPRESSION:-}
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE: ${OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE:-}
OTEL_RESOURCE_ATTRIBUTES: ${OTEL_RESOURCE_ATTRIBUTES:-}
OTEL_SERVICE_NAME: rawtrail-server
secrets:
- enroll_secret
- edr_dsn
- secret_key
- clickhouse_dsn
caddy:
image: caddy:2
restart: unless-stopped
depends_on:
- server
environment:
EDR_DOMAIN: ${EDR_DOMAIN}
ports:
- "80:80"
- "443:443"
volumes:
- ./packaging/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy-data:/data
- caddy-config:/config
volumes:
edr-mysql-data:
edr-clickhouse-data:
caddy-data:
caddy-config:
secrets:
mysql_root:
file: ./secrets/mysql_root
enroll_secret:
file: ./secrets/enroll_secret
edr_dsn:
file: ./secrets/edr_dsn
secret_key:
file: ./secrets/secret_key
clickhouse_dsn:
file: ./secrets/clickhouse_dsn