Skip to content
Learni
View all tutorials
Monitoring

How to Configure Alertmanager in 2026

Lire en français

Introduction

Alertmanager is the key component in the Prometheus ecosystem for smart alert management. Unlike a simple alert relay, it deduplicates, groups, and routes notifications to various receivers like Slack, email, or PagerDuty, preventing alert fatigue during incidents. In 2026, with the rise of cloud-native infrastructures, mastering Alertmanager is essential for any beginner DevOps or SRE.

This tutorial guides you step by step through a complete Docker Compose installation, including Prometheus to generate real alerts. You'll learn to configure YAML routes, access the intuitive web interface, and test a simple webhook receiver. By the end, you'll have a production-ready, scalable setup worth bookmarking. Imagine: a high CPU alert triggers a grouped Slack message—that's the real power we're unlocking here.

Prerequisites

  • Docker and Docker Compose installed (version 20+ recommended)
  • Basic knowledge of YAML and Prometheus (simple concepts explained)
  • A terminal (bash/zsh)
  • Ports 9090, 9093, and 3000 free on localhost
  • Optional: Slack account to test webhooks

Create the project structure

setup.sh
mkdir alertmanager-tutorial
cd alertmanager-tutorial
git init
mkdir -p prometheus/config
mkdir -p alertmanager/config
touch docker-compose.yml
 touch prometheus/config/prometheus.yml
touch prometheus/config/rules.yml
touch alertmanager/config/alertmanager.yml
echo "Alertmanager project ready!"

This bash script initializes a structured project folder with the necessary directories for Prometheus and Alertmanager. It creates all the empty YAML files ready for configuration. Avoid pitfalls by using absolute paths if you're outside a Git workspace.

Configure Docker Compose

Docker Compose orchestrates Prometheus, Alertmanager, and a metrics exporter (node-exporter) to simulate real data. This avoids complex native installations, making the setup portable and reproducible.

docker-compose.yml file

docker-compose.yml
version: '3.8'
services:
  prometheus:
    image: prom/prometheus:v2.54.0
    volumes:
      - ./prometheus/config:/etc/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
    ports:
      - "9090:9090"
    restart: always

  alertmanager:
    image: prom/alertmanager:v0.27.0
    volumes:
      - ./alertmanager/config:/etc/alertmanager
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    ports:
      - "9093:9093"
    restart: always

  node_exporter:
    image: prom/node-exporter:v1.8.2
    ports:
      - "9100:9100"
    restart: always

This docker-compose.yml launches three services: Prometheus (port 9090), Alertmanager (9093), and node-exporter for CPU/memory metrics. Volumes mount your custom YAML configs. Common pitfall: forget quotes on long commands, causing parse errors.

Basic Prometheus configuration

prometheus/config/prometheus.yml
global:
  scrape_interval: 15s

rule_files:
  - "rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - alertmanager:9093

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'node'
    static_configs:
      - targets: ['node_exporter:9100']

Prometheus scrapes metrics every 15s and forwards alerts to Alertmanager on internal port 9093. The alerting section is crucial: without it, no routing happens. Always verify targets to avoid connection refusals in clusters.

Start the services

Now run docker compose up -d in the project folder. Check logs with docker compose logs -f. Access Prometheus at http://localhost:9090 and Alertmanager at http://localhost:9093. Alertmanager's UI already shows silences and configs in real time.

High CPU alert rule

prometheus/config/rules.yml
groups:
- name: example
  rules:
  - alert: HighCPUUsage
    expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
    for: 1m
    labels:
      severity: warning
    annotations:
      summary: "High CPU usage on {{ $labels.instance }}"
      description: "CPU > 80% for more than 1 minute."

This rule triggers an alert if CPU exceeds 80% for 1 minute, with labels and annotations for routing. Reload Prometheus via the UI (Status > Rules) after changes. Analogy: like a guard waiting for confirmation before calling reinforcements.

Basic Alertmanager configuration

alertmanager/config/alertmanager.yml
global:
  smtp_smarthost: 'localhost:1025'
  smtp_from: 'alertmanager@example.com'

route:
  group_by: ['alertname', 'cluster']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: 'default'

receivers:
- name: 'default'
  webhook_configs:
  - url: 'http://httpbin.org/post'

inhibit_rules:
- source_match:
    severity: 'critical'
  target_match:
    severity: 'warning'
  equal: ['alertname', 'cluster', 'service']

Alertmanager groups alerts by name and cluster, waits 30s before sending, and routes to a test webhook (httpbin). Inhibitions prevent duplicates. Restart the container after edits: docker compose restart alertmanager. Pitfall: strict YAML indentation!

Test the alert

Generate high CPU: docker run --rm -it --cpus=0.8 ubuntu:22.04 stress --cpu 8 --timeout 300s in the background. Monitor Prometheus > Graph > CPU query, then Alertmanager UI > Alerts. You'll see the grouped alert!

Add a Slack receiver

alertmanager/config/alertmanager-slack.yml
route:
  receiver: slack
  group_by: ['alertname']

receivers:
- name: slack
  slack_configs:
  - api_url: 'https://hooks.slack.com/services/VOTRE/WEBHOOK'
    channel: '#alerts'
    text: "{{ range .Alerts }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .AnnotatedInstance }} {{ .Annotations.summary }}{{ end }}"
    send_resolved: true

Replace alertmanager.yml with this snippet for Slack (get api_url from Slack App). It formats messages with status and summary. Tested: resolved alerts are sent too. In production, use Docker secrets for integration.

Best practices

  • Strategic group_by: Group by cluster/service to reduce noise (avoid 'instance' alone).
  • Progressive repeat_interval: 1h for warnings, 5min for critical—tailor to SLAs.
  • Use the UI for silences: Silence manually via localhost:9093/#/silences instead of static configs.
  • Monitor Alertmanager: Add it to Prometheus with scrape_config job_name: 'alertmanager'.
  • HA setup: Scale with multiple replicas and Consul for discovery in production.

Common errors to avoid

  • Misindented YAML: Alertmanager won't start—validate with yamllint or your IDE.
  • Port conflicts: Check netstat -tuln | grep 9093 before starting.
  • No rules_files: Silent alerts—reload Prometheus UI after edits.
  • Wrong targets: In Docker, use service names (alertmanager:9093), not localhost.

Next steps