# The Alloy log-collector agent. Runs on EACH node (prod, beta, LAN dev) — one # per node — reading that node's Docker containers, Caddy logs, and the app's # JSON logs, and shipping them to the central Loki on beta over the mesh. # # Per-node config comes from the environment (an .env file next to this, or # exported before `up`): # ALLOY_NODE this node's label: prod | beta | dev # LOKI_URL push endpoint. On beta: http://127.0.0.1:3100/loki/api/v1/push # Elsewhere (over wg0): http://10.10.0.2:3100/loki/api/v1/push # # Deploy on a node: # ALLOY_NODE=prod LOKI_URL=http://10.10.0.2:3100/loki/api/v1/push \ # docker compose -f docker-compose.agent.yml up -d # # The app's JSON logs are read from its `applogs` Docker volume, named # `_applogs`. prod and beta run the app under the compose project # `thermograph`, so the external volume below is `thermograph_applogs`. The LAN # dev stack uses the project `thermograph-dev` — on that node, change the two # `thermograph_applogs` references below to `thermograph-dev_applogs`. services: alloy: image: grafana/alloy:v1.9.1 command: - run - /etc/alloy/config.alloy - --storage.path=/var/lib/alloy/data - --server.http.listen-addr=0.0.0.0:12345 environment: ALLOY_NODE: ${ALLOY_NODE:?set ALLOY_NODE (prod|beta|dev)} LOKI_URL: ${LOKI_URL:?set LOKI_URL} volumes: - ./config.alloy:/etc/alloy/config.alloy:ro # Read-only Docker socket: discover + tail every container's stdout/stderr. - /var/run/docker.sock:/var/run/docker.sock:ro # Caddy's host access logs (runs on the host, not a container). - /var/log/caddy:/var/log/caddy:ro # The app's structured JSON logs, straight off its named volume. - thermograph_applogs:/applogs:ro - alloy_data:/var/lib/alloy/data restart: unless-stopped volumes: # The app's existing log volume (created by the app's own stack). external:true # means compose references it, never creates or deletes it. thermograph_applogs: external: true alloy_data: {}