ObservaStack

docker-compose.yml

# Not executed here. This box has no Docker. Images are pinned by digest.
# Named volumes hold Prometheus, Alertmanager, and Grafana state. There is no
# repo directory named data. Grafana's admin password comes from the environment.
# PROMETHEUS_URL is what grafana/provisioning/datasources/prometheus.yml reads.

services:
  prometheus:
    image: prom/prometheus:v3.15.0@sha256:efd719c99d83b060d9daefdcf00360461adf279f45ef5391f8d111892118753e
    command:
      - --config.file=/etc/observastack/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
      - --web.listen-address=:9090
    volumes:
      - .:/etc/observastack:ro
      - prom_tsdb:/prometheus
    ports:
      - "127.0.0.1:9090:9090"
    mem_limit: 512m
    cpus: 0.50
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:9090/-/healthy"]
      interval: 15s
      timeout: 5s
      retries: 5

  alertmanager:
    image: prom/alertmanager:v0.34.1@sha256:e9733bafb1bdef9b00e25a21f8f99dc26a22224bf16641ad754d1649f4c3357a
    command:
      - --config.file=/etc/observastack/alertmanager/alertmanager.yml
      - --storage.path=/alertmanager
      - --web.listen-address=:9093
    working_dir: /etc/observastack
    volumes:
      - .:/etc/observastack:ro
      - am_store:/alertmanager
    ports:
      - "127.0.0.1:9093:9093"
    mem_limit: 256m
    cpus: 0.25
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:9093/-/healthy"]
      interval: 15s
      timeout: 5s
      retries: 5

  grafana:
    image: grafana/grafana:13.2.3@sha256:b28bae15e219c998fb0e0424ed724930cc61b1f61fb404d47c862f9a23f9e572
    environment:
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: ${GF_SECURITY_ADMIN_PASSWORD:?set GF_SECURITY_ADMIN_PASSWORD}
      GF_ANALYTICS_REPORTING_ENABLED: "false"
      GF_ANALYTICS_CHECK_FOR_UPDATES: "false"
      GF_PLUGINS_PREINSTALL_DISABLED: "true"
      GF_PATHS_PROVISIONING: /etc/observastack/grafana/provisioning
      PROMETHEUS_URL: http://prometheus:9090
    volumes:
      - .:/etc/observastack:ro
      - grafana_store:/var/lib/grafana
    ports:
      - "127.0.0.1:3000:3000"
    mem_limit: 512m
    cpus: 0.50
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:3000/api/health"]
      interval: 15s
      timeout: 5s
      retries: 8

  node-exporter:
    image: prom/node-exporter:v1.9.1@sha256:d00a542e409ee618a4edc67da14dd48c5da66726bbd5537ab2af9c1dfc442c8a
    mem_limit: 128m
    cpus: 0.20
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:9100/metrics"]
      interval: 15s
      timeout: 5s
      retries: 5

  postgres-exporter:
    image: prometheuscommunity/postgres-exporter:v0.17.1@sha256:38606faa38c54787525fb0ff2fd6b41b4cfb75d455c1df294927c5f611699b17
    environment:
      DATA_SOURCE_NAME: ${POSTGRES_EXPORTER_DSN:-postgresql://[email protected]:5432/larkspur?sslmode=disable}
    mem_limit: 128m
    cpus: 0.20
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:9187/metrics"]
      interval: 15s
      timeout: 5s
      retries: 5

  blackbox-exporter:
    image: prom/blackbox-exporter:v0.26.0@sha256:92e05d5fe0df01d3980518dc42f07b778a8997048b57392ebc7f7391ebd7bb06
    command:
      - --config.file=/etc/observastack/exporters/blackbox.yml
    volumes:
      - .:/etc/observastack:ro
    mem_limit: 128m
    cpus: 0.20
    healthcheck:
      test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:9115/metrics"]
      interval: 15s
      timeout: 5s
      retries: 5

  demo-app:
    build:
      context: .
      dockerfile: demo-app/Dockerfile
    image: observastack-demo-app:local
    mem_limit: 128m
    cpus: 0.20
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/healthz')"]
      interval: 15s
      timeout: 5s
      retries: 5

volumes:
  prom_tsdb: {}
  am_store: {}
  grafana_store: {}