Configure Prometheus Alertmanager with Slack integration for team notifications

Intermediate 25 min May 29, 2026 120 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up Prometheus Alertmanager to route alerts to Slack channels with custom notification rules. Configure alerting rules, webhook integration, and team-based routing for production monitoring workflows.

Prerequisites

  • Prometheus server already installed
  • Slack workspace with admin access
  • Basic knowledge of YAML configuration

What this solves

Prometheus Alertmanager receives alerts from Prometheus and routes them to notification channels like Slack, email, or PagerDuty. This tutorial shows you how to configure Alertmanager with Slack integration, set up custom routing rules, and create alerting policies for different teams and severity levels.

Step-by-step installation

Update system packages

Start by updating your package manager to ensure you get the latest versions.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Create system user for Alertmanager

Create a dedicated system user to run Alertmanager securely without shell access.

sudo useradd --no-create-home --shell /bin/false alertmanager
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo chown alertmanager:alertmanager /etc/alertmanager /var/lib/alertmanager

Download and install Alertmanager

Download the latest Alertmanager binary and install it to the system PATH.

cd /tmp
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
tar xzf alertmanager-0.27.0.linux-amd64.tar.gz
sudo cp alertmanager-0.27.0.linux-amd64/alertmanager /usr/local/bin/
sudo cp alertmanager-0.27.0.linux-amd64/amtool /usr/local/bin/
sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager /usr/local/bin/amtool

Set up Slack webhook integration

Create a Slack webhook URL for your workspace. Go to your Slack workspace, navigate to Apps, search for "Incoming Webhooks", and create a new webhook for your target channel.

Note: Copy the webhook URL starting with https://hooks.slack.com/services/. You'll need this for the Alertmanager configuration.

Create Alertmanager configuration

Configure Alertmanager with Slack integration, routing rules, and notification templates.

global:
  smtp_smarthost: 'localhost:587'
  smtp_from: 'alertmanager@example.com'
  slack_api_url: 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'

route:
  group_by: ['alertname', 'instance']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 12h
  receiver: 'web.hook'
  routes:
  - match:
      severity: critical
    receiver: 'critical-alerts'
    group_wait: 10s
    repeat_interval: 1h
  - match:
      severity: warning
    receiver: 'warning-alerts'
    group_wait: 30s
    repeat_interval: 6h
  - match:
      team: database
    receiver: 'database-team'
  - match:
      team: frontend
    receiver: 'frontend-team'

receivers:
  • name: 'web.hook'
slack_configs: - channel: '#alerts' title: 'Prometheus Alert' text: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}' send_resolved: true
  • name: 'critical-alerts'
slack_configs: - channel: '#critical-alerts' title: 'CRITICAL: {{ .GroupLabels.alertname }}' text: | {{ range .Alerts }} Alert: {{ .Annotations.summary }} Description: {{ .Annotations.description }} Instance: {{ .Labels.instance }} Severity: {{ .Labels.severity }} {{ end }} color: 'danger' send_resolved: true
  • name: 'warning-alerts'
slack_configs: - channel: '#warnings' title: 'Warning: {{ .GroupLabels.alertname }}' text: | {{ range .Alerts }} Alert: {{ .Annotations.summary }} Instance: {{ .Labels.instance }} {{ end }} color: 'warning' send_resolved: true
  • name: 'database-team'
slack_configs: - channel: '#database-alerts' title: 'Database Alert: {{ .GroupLabels.alertname }}' text: | {{ range .Alerts }} Database Alert: {{ .Annotations.summary }} Instance: {{ .Labels.instance }} Team: {{ .Labels.team }} {{ end }} send_resolved: true
  • name: 'frontend-team'
slack_configs: - channel: '#frontend-alerts' title: 'Frontend Alert: {{ .GroupLabels.alertname }}' text: | {{ range .Alerts }} Frontend Alert: {{ .Annotations.summary }} Instance: {{ .Labels.instance }} Team: {{ .Labels.team }} {{ end }} send_resolved: true inhibit_rules:
  • source_match:
severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'instance']

Configure Prometheus alerting rules

Create alerting rules that Prometheus will evaluate and send to Alertmanager.

groups:
  • name: system_alerts
rules: - alert: HighCPUUsage expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80 for: 5m labels: severity: warning team: infrastructure annotations: summary: "High CPU usage on {{ $labels.instance }}" description: "CPU usage is above 80% for more than 5 minutes on {{ $labels.instance }}" - alert: HighMemoryUsage expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 85 for: 5m labels: severity: warning team: infrastructure annotations: summary: "High memory usage on {{ $labels.instance }}" description: "Memory usage is above 85% on {{ $labels.instance }}" - alert: DiskSpaceLow expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 10 for: 2m labels: severity: critical team: infrastructure annotations: summary: "Low disk space on {{ $labels.instance }}" description: "Disk space is below 10% on {{ $labels.instance }}" - alert: ServiceDown expr: up == 0 for: 1m labels: severity: critical team: infrastructure annotations: summary: "Service down: {{ $labels.job }}" description: "Service {{ $labels.job }} on {{ $labels.instance }} is down"
  • name: database_alerts
rules: - alert: PostgreSQLDown expr: pg_up == 0 for: 1m labels: severity: critical team: database annotations: summary: "PostgreSQL is down on {{ $labels.instance }}" description: "PostgreSQL database is not responding on {{ $labels.instance }}" - alert: PostgreSQLTooManyConnections expr: sum(pg_stat_activity_count) by (instance) > 80 for: 5m labels: severity: warning team: database annotations: summary: "Too many PostgreSQL connections on {{ $labels.instance }}" description: "PostgreSQL has {{ $value }} active connections on {{ $labels.instance }}"
  • name: web_alerts
rules: - alert: WebsiteDown expr: probe_success == 0 for: 1m labels: severity: critical team: frontend annotations: summary: "Website is down: {{ $labels.instance }}" description: "Website {{ $labels.instance }} is not responding to health checks" - alert: HighResponseTime expr: probe_duration_seconds > 5 for: 5m labels: severity: warning team: frontend annotations: summary: "High response time for {{ $labels.instance }}" description: "Response time is {{ $value }}s for {{ $labels.instance }}" - alert: NginxDown expr: nginx_up == 0 for: 1m labels: severity: critical team: frontend annotations: summary: "Nginx is down on {{ $labels.instance }}" description: "Nginx web server is not responding on {{ $labels.instance }}"

Update Prometheus configuration

Configure Prometheus to load the alerting rules and send alerts to Alertmanager.

global:
  scrape_interval: 15s
  evaluation_interval: 15s

rule_files:
  - "alert_rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - localhost:9093

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

  - job_name: 'node-exporter'
    static_configs:
      - targets: ['localhost:9100']

  - job_name: 'alertmanager'
    static_configs:
      - targets: ['localhost:9093']

Set correct file permissions

Ensure Alertmanager can read its configuration files with proper ownership and permissions.

sudo chown -R alertmanager:alertmanager /etc/alertmanager
sudo chmod 755 /etc/alertmanager
sudo chmod 644 /etc/alertmanager/alertmanager.yml
sudo chown -R prometheus:prometheus /etc/prometheus
sudo chmod 644 /etc/prometheus/alert_rules.yml
Never use chmod 777. It gives every user on the system full access to your files. Instead, use specific ownership with chown and minimal permissions for security.

Create systemd service

Set up Alertmanager as a systemd service for automatic startup and process management.

[Unit]
Description=Alertmanager
Wants=network-online.target
After=network-online.target

[Service]
User=alertmanager
Group=alertmanager
Type=simple
WorkingDirectory=/var/lib/alertmanager
ExecStart=/usr/local/bin/alertmanager \
  --config.file=/etc/alertmanager/alertmanager.yml \
  --storage.path=/var/lib/alertmanager \
  --web.external-url=http://localhost:9093 \
  --web.route-prefix=/ \
  --cluster.listen-address=0.0.0.0:9094
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target

Start and enable services

Enable both Prometheus and Alertmanager services to start automatically on boot.

sudo systemctl daemon-reload
sudo systemctl enable --now alertmanager
sudo systemctl restart prometheus
sudo systemctl status alertmanager
sudo systemctl status prometheus

Configure firewall access

Open the necessary ports for Alertmanager web interface and cluster communication.

sudo ufw allow 9093/tcp comment "Alertmanager web interface"
sudo ufw allow 9094/tcp comment "Alertmanager cluster"
sudo firewall-cmd --permanent --add-port=9093/tcp
sudo firewall-cmd --permanent --add-port=9094/tcp
sudo firewall-cmd --reload

Testing Slack integration

Send test alert

Use amtool to send a test alert and verify Slack integration is working.

amtool alert add test_alert alertname="TestAlert" severity="warning" instance="localhost" summary="Test alert from Alertmanager" --alertmanager.url=http://localhost:9093

Trigger CPU alert for testing

Create artificial CPU load to test your alerting rules and Slack notifications.

timeout 300s yes > /dev/null &
timeout 300s yes > /dev/null &
timeout 300s yes > /dev/null &
timeout 300s yes > /dev/null &
Note: This creates CPU load for 5 minutes to trigger the HighCPUUsage alert. Check your Slack channel for notifications.

Verify your setup

sudo systemctl status alertmanager
curl -s http://localhost:9093/-/healthy
curl -s http://localhost:9093/api/v1/status
amtool config show --alertmanager.url=http://localhost:9093
amtool alert query --alertmanager.url=http://localhost:9093

Access the Alertmanager web interface at http://your-server-ip:9093 to view active alerts and configuration status. The interface shows current alerts, silences, and routing information.

Advanced configuration

Configure alert silencing

Set up maintenance windows and alert silencing for planned downtime.

amtool silence add alertname="HighCPUUsage" instance="server1.example.com" --duration="2h" --comment="Planned maintenance" --alertmanager.url=http://localhost:9093
amtool silence query --alertmanager.url=http://localhost:9093

Add email notifications

Configure email notifications as a backup to Slack for critical alerts.

- name: 'critical-email'
  email_configs:
  - to: 'oncall@example.com'
    from: 'alertmanager@example.com'
    subject: 'CRITICAL: {{ .GroupLabels.alertname }}'
    body: |
      {{ range .Alerts }}
      Alert: {{ .Annotations.summary }}
      Description: {{ .Annotations.description }}
      Instance: {{ .Labels.instance }}
      Severity: {{ .Labels.severity }}
      {{ end }}
  slack_configs:
  - channel: '#critical-alerts'
    title: 'CRITICAL: {{ .GroupLabels.alertname }}'
    text: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}'
    color: 'danger'
    send_resolved: true

Common issues

Symptom Cause Fix
Alertmanager won't start Configuration syntax error amtool config check /etc/alertmanager/alertmanager.yml
No Slack notifications received Invalid webhook URL or channel Test webhook URL manually with curl, verify channel exists
Alerts not firing Prometheus not loading rules curl http://localhost:9090/api/v1/rules to check loaded rules
Permission denied errors Incorrect file ownership sudo chown -R alertmanager:alertmanager /etc/alertmanager
Web interface shows "Unhealthy" Storage path not accessible Check /var/lib/alertmanager permissions and disk space
Too many duplicate notifications Incorrect grouping configuration Adjust group_interval and repeat_interval settings

Next steps

Running this in production?

Want this handled for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and performant across environments is the harder part. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle managed devops services for businesses that depend on uptime. From initial setup to ongoing operations.