Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Alertmanager Ubuntu
GUIDEInstall Guides

How to Install Prometheus Alertmanager on Ubuntu 24.04

21 min read

How to Install Prometheus Alertmanager on Ubuntu 24.04

Monitoring without alerting is just a pretty dashboard. Prometheus is excellent at scraping metrics and evaluating alert rules, but it does not deliver notifications on its own — that job belongs to Alertmanager. This tutorial walks you through installing Alertmanager on an Ubuntu 24.04 VPS, from a single systemd-managed binary up to a highly-available cluster with email, Slack, PagerDuty, and webhook receivers behind a TLS-terminated Nginx reverse proxy.

By the end of this guide, you will have a production-ready alerting pipeline: Prometheus fires alerts, Alertmanager groups and deduplicates them, routes each notification to the right team via the right channel, suppresses noisy follow-ups with inhibition rules, and respects silences during maintenance windows.

Want a quick monitoring host? Deploy a lean VPS from our Starter plan at EUR 7.99/month and follow along — Alertmanager sips resources and runs comfortably on 2 GB of RAM.

Table of Contents

  • What is Alertmanager?
  • Why Self-Host Alerting Instead of PagerDuty-Only?
  • Prerequisites
  • Step 1: Update System Packages
  • Step 2: Create the alertmanager System User
  • Step 3: Download and Install the Alertmanager Binary
  • Step 4: Create the systemd Unit
  • Step 5: Write alertmanager.yml
  • Step 6: Integrate with Prometheus
  • Step 7: Expose Alertmanager Behind Nginx with TLS
  • Step 8: Inhibition Rules, Silences, and Templates
  • Step 9: High-Availability Clustering
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Alertmanager?

    Alertmanager is the notification layer of the Prometheus ecosystem. Prometheus servers evaluate alerting rules (for example, "CPU above 90% for 5 minutes") and push the resulting alerts to Alertmanager over HTTP. Alertmanager then handles the human side of the problem: deduplicating duplicates from multiple Prometheus replicas, grouping related alerts into a single notification, routing based on labels, throttling repeat notifications, silencing expected events during maintenance, and finally dispatching to email, Slack, PagerDuty, Opsgenie, webhooks, or any of the two dozen built-in integrations.

    The routing logic is the core feature. You define a route tree where the root matches everything and child routes match on labels. An alert with severity: critical and team: payments might be routed to the payments team's PagerDuty on-call, while severity: warning for the same team goes to a Slack channel, and anything from a staging cluster is silenced except during business hours. This tree replaces a sprawl of if/else statements in a dozen different monitoring tools with a single declarative YAML file that reviewers can read in a pull request.

    Alertmanager also solves problems that are surprisingly hard to get right. Deduplication matters when you run Prometheus in HA mode — two replicas both fire the same alert, and without Alertmanager you get paged twice. Grouping matters when a single rack loses power and fifty services fire at once — you want one notification listing all affected services, not fifty SMS messages. Inhibition matters when a parent alert ("entire datacenter unreachable") should suppress child alerts ("each individual service unreachable") so on-call gets the actionable signal and not the noise.

    Why Self-Host Alerting Instead of PagerDuty-Only?

    A common question: if you already pay for PagerDuty (or Opsgenie, or Splunk On-Call), why bother running Alertmanager? There are several good reasons to put Alertmanager in front of those services rather than pointing Prometheus directly at them:

    • Label-based routing is free and expressive. PagerDuty's routing rules are per-service and require paid tiers for anything sophisticated. Alertmanager's YAML-defined tree costs nothing and lives in your git repo alongside the alert rules themselves — change review, blame, and rollback all come for free.
    • Deduplication across HA Prometheus pairs. If you run two Prometheus replicas for redundancy, both will fire the same alert. PagerDuty will happily open two incidents. A pair of clustered Alertmanagers dedupe the alert into one notification before it ever leaves your network.
    • Grouping stops alert storms. A database outage that takes down 40 downstream services is one incident, not 40. Alertmanager's group_by flattens the storm; PagerDuty will not.
    • Silences are cheap and auditable. Before a planned deployment, a single amtool silence add command mutes the affected services for 30 minutes across every notification channel. Doing the same in a SaaS on-call tool typically requires clicking through a UI per service.
    • Per-receiver fan-out. The same alert can simultaneously create a PagerDuty incident, post to Slack, send an email to a compliance mailbox, and hit an internal webhook — without paying for multi-channel features in the SaaS tool.
    • Data sovereignty. Alert labels often include hostnames, internal service names, IP ranges, and customer IDs. Routing those through a third party involves contracts and, in some regulated environments, is simply not allowed. A self-hosted Alertmanager keeps the sensitive payload internal and only forwards sanitised summaries to external services.
    • Cost. Alertmanager on a EUR 7.99/month Starter VPS handles tens of thousands of alerts per day. PagerDuty charges per user per month and adds surcharges for retention, advanced routing, and analytics.
    The pattern most teams converge on is: Prometheus → Alertmanager (self-hosted, HA pair) → {PagerDuty for severity=critical, Slack for severity=warning, email for severity=info}. Alertmanager is the router; the SaaS tool is just one of several downstream receivers.

    Prerequisites

    Before you begin, make sure you have:

    • An Ubuntu 24.04 LTS VPS with sudo access.
    • SSH access to the server.
    • At least 1 GB of RAM (2 GB comfortably handles even noisy environments).
    • A running Prometheus instance that you will point at Alertmanager.
    • Credentials for at least one receiver — an SMTP relay, a Slack incoming webhook URL, a PagerDuty integration key, or a target webhook URL.
    • A DNS record (for example, alerts.yourdomain.com) pointing at your VPS if you plan to expose the UI behind TLS.
    Recommended Plan: Starter
    >
    Alertmanager is not resource-hungry. The CloudCore Starter plan gives you:
    >
    - 2 vCPU cores
    - 2 GB RAM
    - 50 GB NVMe SSD
    - Unmetered bandwidth
    - EUR 7.99/month
    >
    This is enough to run Alertmanager plus a small Prometheus or a VictoriaMetrics agent. For full monitoring stacks (Prometheus + Alertmanager + Grafana + Loki), consider sizing up.

    Connect to your server:

    bash
    ssh root@your-server-ip

    Step 1: Update System Packages

    bash
    sudo apt update && sudo apt upgrade -y

    Install the utilities we will need along the way:

    bash
    sudo apt install -y curl wget tar ufw

    If the kernel was upgraded, reboot before continuing:

    bash
    sudo reboot

    Step 2: Create the alertmanager System User

    Run Alertmanager under its own unprivileged user so that the process cannot read unrelated files on the host.

    bash
    sudo useradd --system --no-create-home --shell /bin/false alertmanager

    Create the directories Alertmanager will use for configuration, binary storage, and state:

    bash
    sudo mkdir -p /etc/alertmanager /var/lib/alertmanager /etc/alertmanager/templates
    sudo chown -R alertmanager:alertmanager /etc/alertmanager /var/lib/alertmanager

    /var/lib/alertmanager holds the notification log (nflog) and silences database — both must persist across restarts so that notifications are not duplicated and silences are not lost.

    Step 3: Download and Install the Alertmanager Binary

    Fetch the latest release from the Prometheus GitHub releases page. At the time of writing, the current version is 0.27.0; swap in whatever is current when you follow this tutorial.

    bash
    cd /tmp
    ALERTMANAGER_VERSION="0.27.0"
    wget https://github.com/prometheus/alertmanager/releases/download/v${ALERTMANAGER_VERSION}/alertmanager-${ALERTMANAGER_VERSION}.linux-amd64.tar.gz
    tar xzf alertmanager-${ALERTMANAGER_VERSION}.linux-amd64.tar.gz
    cd alertmanager-${ALERTMANAGER_VERSION}.linux-amd64

    Install the two binaries: alertmanager is the server, amtool is the companion CLI for managing silences and validating configs.

    bash
    sudo install -o root -g root -m 0755 alertmanager /usr/local/bin/alertmanager
    sudo install -o root -g root -m 0755 amtool        /usr/local/bin/amtool

    Verify:

    bash
    alertmanager --version
    amtool --version

    Expected output:

    text
    alertmanager, version 0.27.0 (branch: HEAD, revision: 0aa3c2aad14cff039931923ab16b26b7481783b5)
      build user:       root@22cd11f671e9
      build date:       20240228-11:51:20
      go version:       go1.21.7

    Clean up the download:

    bash
    rm -rf /tmp/alertmanager-${ALERTMANAGER_VERSION}.linux-amd64*

    Step 4: Create the systemd Unit

    bash
    sudo tee /etc/systemd/system/alertmanager.service > /dev/null <<'EOF'
    [Unit]
    Description=Prometheus Alertmanager
    Documentation=https://prometheus.io/docs/alerting/latest/alertmanager/
    Wants=network-online.target
    After=network-online.target

    [Service] User=alertmanager Group=alertmanager Type=simple Restart=on-failure RestartSec=5s ExecStart=/usr/local/bin/alertmanager \ --config.file=/etc/alertmanager/alertmanager.yml \ --storage.path=/var/lib/alertmanager \ --web.listen-address=127.0.0.1:9093 \ --web.external-url=https://alerts.yourdomain.com \ --cluster.listen-address=0.0.0.0:9094 \ --log.level=info

    Hardening

    NoNewPrivileges=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/var/lib/alertmanager PrivateTmp=true PrivateDevices=true ProtectKernelTunables=true ProtectControlGroups=true RestrictSUIDSGID=true LockPersonality=true

    [Install] WantedBy=multi-user.target EOF

    Key flags explained:

    • --config.file — path to the YAML config you will write in the next step.
    • --storage.path — where silences and the notification log persist.
    • --web.listen-address=127.0.0.1:9093 — bind to localhost only; Nginx will terminate TLS publicly and proxy in.
    • --web.external-url — tells Alertmanager what URL clients see (needed for correct links in notifications and for the UI to build absolute links).
    • --cluster.listen-address=0.0.0.0:9094 — the gossip port for HA clustering. Harmless when running a single node; required when you add peers in Step 9.
    Reload systemd but do not start the service yet — it will fail without a valid config.

    bash
    sudo systemctl daemon-reload

    Step 5: Write alertmanager.yml

    This is the heart of Alertmanager. The config has three logical sections: the top-level global defaults, the route tree, and the list of receivers the tree points at. We will also add inhibit_rules and a templates directive.

    bash
    sudo tee /etc/alertmanager/alertmanager.yml > /dev/null <<'EOF'
    global:
      resolve_timeout: 5m
      smtp_from: "[email protected]"
      smtp_smarthost: "smtp.mailgun.org:587"
      smtp_auth_username: "[email protected]"
      smtp_auth_password: "REPLACE_WITH_SMTP_PASSWORD"
      smtp_require_tls: true
      slack_api_url: "https://hooks.slack.com/services/T000/B000/REPLACE_WITH_WEBHOOK"

    templates: - "/etc/alertmanager/templates/*.tmpl"

    route: receiver: "default-email" group_by: ["alertname", "cluster", "service"] group_wait: 30s group_interval: 5m repeat_interval: 4h routes: # Critical production alerts page on-call via PagerDuty + Slack - matchers: - severity = "critical" - env = "prod" receiver: "pagerduty-prod" group_wait: 10s continue: true

    - matchers: - severity = "critical" - env = "prod" receiver: "slack-incidents" continue: false

    # Warnings in prod go to Slack only - matchers: - severity = "warning" - env = "prod" receiver: "slack-warnings"

    # Staging gets a single low-traffic Slack channel - matchers: - env = "staging" receiver: "slack-staging" group_interval: 15m repeat_interval: 12h

    # Anything tagged webhook-only gets forwarded to the internal incident bot - matchers: - route = "webhook" receiver: "internal-webhook"

    inhibit_rules: # If an entire cluster is down, suppress the per-service alerts from it - source_matchers: [alertname = "ClusterDown"] target_matchers: [severity =~ "warning|critical"] equal: [cluster]

    # Critical always wins over warning for the same alert/instance - source_matchers: [severity = "critical"] target_matchers: [severity = "warning"] equal: [alertname, cluster, service, instance]

    receivers: - name: "default-email" email_configs: - to: "[email protected]" send_resolved: true

    - name: "pagerduty-prod" pagerduty_configs: - routing_key: "REPLACE_WITH_PD_INTEGRATION_KEY" severity: "{{ .CommonLabels.severity }}" description: "{{ .CommonAnnotations.summary }}" details: firing: "{{ .Alerts.Firing | len }}" resolved: "{{ .Alerts.Resolved | len }}" runbook: "{{ .CommonAnnotations.runbook_url }}" send_resolved: true

    - name: "slack-incidents" slack_configs: - channel: "#incidents" send_resolved: true title: '{{ template "slack.title" . }}' text: '{{ template "slack.text" . }}'

    - name: "slack-warnings" slack_configs: - channel: "#alerts-warnings" send_resolved: true

    - name: "slack-staging" slack_configs: - channel: "#alerts-staging" send_resolved: false

    - name: "internal-webhook" webhook_configs: - url: "http://incident-bot.internal:8080/hooks/alertmanager" send_resolved: true max_alerts: 50 EOF

    sudo chown alertmanager:alertmanager /etc/alertmanager/alertmanager.yml sudo chmod 0640 /etc/alertmanager/alertmanager.yml

    Validate the config before starting the service — a typo here will keep the daemon from launching:

    bash
    amtool check-config /etc/alertmanager/alertmanager.yml

    Expected output:

    text
    Checking '/etc/alertmanager/alertmanager.yml'  SUCCESS
    Found:
     - global config
     - route
     - 2 inhibit rules
     - 6 receivers
     - 1 templates

    Start the service:

    bash
    sudo systemctl enable --now alertmanager
    sudo systemctl status alertmanager

    You should see active (running). Curl the UI locally to confirm:

    bash
    curl -s http://127.0.0.1:9093/-/healthy
    

    OK

    Understanding the Route Tree

    The route tree is evaluated top-down, depth-first. Every alert starts at the root and matches only the most specific branch — unless you set continue: true, which lets matching fall through to subsequent sibling routes. That is how the config above sends the same critical-prod alert to both PagerDuty and Slack: the PagerDuty route has continue: true, so evaluation continues and matches the Slack route too.

    • group_by — labels that define an alert group. All alerts with the same values for these labels are collapsed into one notification.
    • group_wait — how long to wait after the first alert in a new group arrives before sending, in case more related alerts are about to fire. 30s is typical.
    • group_interval — how long to wait before sending an update to an existing group when new alerts join it.
    • repeat_interval — if alerts are still firing, how often to resend the notification. 4 hours is a sane default; critical routes often override this.

    Step 6: Integrate with Prometheus

    Alertmanager is useless unless Prometheus is pushing alerts at it. Edit your Prometheus config (typically /etc/prometheus/prometheus.yml) and add the alerting block:

    yaml
    alerting:
      alertmanagers:
        - static_configs:
            - targets:
                - 127.0.0.1:9093
          # When you cluster Alertmanager, list all peers here so Prometheus
          # sends each alert to every instance. Alertmanager dedupes them.

    rule_files: - /etc/prometheus/rules/*.yml

    Create a sample rule file that demonstrates the labels your Alertmanager routes match on:

    bash
    sudo tee /etc/prometheus/rules/node-basic.yml > /dev/null <<'EOF'
    groups:
      - name: node-basic
        rules:
          - alert: NodeHighCPU
            expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
            for: 10m
            labels:
              severity: warning
              env: prod
            annotations:
              summary: "High CPU on {{ $labels.instance }}"
              description: "CPU above 90% for 10 minutes on {{ $labels.instance }}."
              runbook_url: "https://runbooks.yourdomain.com/node-high-cpu"

    - alert: NodeDown expr: up{job="node"} == 0 for: 2m labels: severity: critical env: prod annotations: summary: "Node {{ $labels.instance }} is DOWN" runbook_url: "https://runbooks.yourdomain.com/node-down" EOF

    sudo systemctl reload prometheus

    Visit the Prometheus UI at http://your-server:9090/alerts and confirm the rules are loaded. Visit http://your-server:9090/status and confirm Alertmanager is listed as a configured endpoint.

    Step 7: Expose Alertmanager Behind Nginx with TLS

    The UI is useful but not something you want exposed to the public internet on a plain HTTP port. Put Nginx in front, terminate TLS with Let's Encrypt, and add basic auth.

    bash
    sudo apt install -y nginx apache2-utils certbot python3-certbot-nginx
    sudo htpasswd -c /etc/nginx/.alertmanager-htpasswd opsuser

    Write the vhost:

    bash
    sudo tee /etc/nginx/sites-available/alertmanager > /dev/null <<'EOF'
    server {
        listen 80;
        server_name alerts.yourdomain.com;
        return 301 https://$host$request_uri;
    }

    server { listen 443 ssl http2; server_name alerts.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/alerts.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/alerts.yourdomain.com/privkey.pem;

    add_header Strict-Transport-Security "max-age=31536000" always; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options DENY;

    location / { auth_basic "Alertmanager"; auth_basic_user_file /etc/nginx/.alertmanager-htpasswd;

    proxy_pass http://127.0.0.1:9093; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }

    # Allow Prometheus to POST alerts without basic auth by locking it to localhost location /api/v2/alerts { allow 127.0.0.1; deny all; proxy_pass http://127.0.0.1:9093; } } EOF

    sudo ln -s /etc/nginx/sites-available/alertmanager /etc/nginx/sites-enabled/ sudo certbot --nginx -d alerts.yourdomain.com sudo nginx -t && sudo systemctl reload nginx

    Lock the firewall down so only 80 (for ACME renewals), 443, and SSH are public. Keep 9093 and 9094 internal:

    bash
    sudo ufw allow 22/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable

    Step 8: Inhibition Rules, Silences, and Templates

    Inhibition

    You already added two inhibition rules in Step 5. They are worth calling out because misunderstanding them is the single most common cause of "Alertmanager is still paging me during the outage I'm already fixing."

    An inhibition rule says: when a source alert is firing, suppress target alerts that share the same value for the listed equal labels. So ClusterDown in a given cluster suppresses every other warning or critical alert tagged with that same cluster. You get one page for the real cause instead of a cascade.

    Silences

    Silences are manual, time-bounded mutes — perfect for planned maintenance. Create one with amtool:

    bash
    amtool --alertmanager.url=http://127.0.0.1:9093 silence add \
      alertname=NodeHighCPU \
      instance=web-03 \
      --duration=2h \
      --comment="Planned load test, YB 2026-04-16"

    List active silences:

    bash
    amtool --alertmanager.url=http://127.0.0.1:9093 silence query

    Expire a silence:

    bash
    amtool --alertmanager.url=http://127.0.0.1:9093 silence expire <silence-id>

    Silences also have a point-and-click creator in the web UI at /#/silences.

    Templates

    Slack and email notifications look dreary out of the box. Drop a template file into /etc/alertmanager/templates/:

    bash
    sudo tee /etc/alertmanager/templates/slack.tmpl > /dev/null <<'EOF'
    {{ define "slack.title" }}
    [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }}
    {{ end }}

    {{ define "slack.text" }} {{ range .Alerts }} Summary: {{ .Annotations.summary }} Severity: {{ .Labels.severity }} | Env: {{ .Labels.env }} | Cluster: {{ .Labels.cluster }} Description: {{ .Annotations.description }} {{ if .Annotations.runbook_url }}Runbook: <{{ .Annotations.runbook_url }}|open>{{ end }} {{ end }} {{ end }} EOF

    sudo chown alertmanager:alertmanager /etc/alertmanager/templates/slack.tmpl sudo systemctl reload alertmanager

    The templates: directive in alertmanager.yml globs this file in automatically. Update the receiver's title and text fields to use {{ template "slack.title" . }} as shown earlier.

    Step 9: High-Availability Clustering

    A single Alertmanager is a single point of failure. For production, run at least two — ideally three — nodes that gossip over the cluster port and cooperate on deduplication and silence propagation.

    Assume you have three hosts: am-1, am-2, am-3, each reachable at their private IPs.

    On every node, adjust the systemd ExecStart to declare peers:

    text
    ExecStart=/usr/local/bin/alertmanager \
      --config.file=/etc/alertmanager/alertmanager.yml \
      --storage.path=/var/lib/alertmanager \
      --web.listen-address=127.0.0.1:9093 \
      --web.external-url=https://alerts.yourdomain.com \
      --cluster.listen-address=0.0.0.0:9094 \
      --cluster.peer=am-1.internal:9094 \
      --cluster.peer=am-2.internal:9094 \
      --cluster.peer=am-3.internal:9094 \
      --log.level=info

    Each node lists all peers including itself — Alertmanager ignores the self entry at startup. Reload and restart on every node:

    bash
    sudo systemctl daemon-reload
    sudo systemctl restart alertmanager

    Confirm the cluster is healthy:

    bash
    curl -s http://127.0.0.1:9093/api/v2/status | jq '.cluster'

    Expected output:

    json
    {
      "name": "01HX...",
      "peers": [
        { "name": "01HX...", "address": "10.0.0.11:9094" },
        { "name": "01HX...", "address": "10.0.0.12:9094" },
        { "name": "01HX...", "address": "10.0.0.13:9094" }
      ],
      "status": "ready"
    }

    On the Prometheus side, list every Alertmanager in the cluster under alertmanagers.static_configs.targets. Prometheus sends each alert to every listed Alertmanager; the cluster gossips and deduplicates so that only one notification goes out to the receivers, even though N Prometheus-to-Alertmanager HTTP calls took place.

    Make sure UDP and TCP 9094 are reachable between cluster members (private network firewall rules — never expose 9094 to the public internet).

    Troubleshooting

    ProblemCauseSolution
    amtool check-config fails with "no route provided"Missing top-level route: blockEnsure route: is present with at least a receiver: field
    Prometheus shows Alertmanager DOWN in /statusWrong port or firewallConfirm Alertmanager listens on 127.0.0.1:9093 and Prometheus targets match
    No notifications arriving but alerts are firing in /alertsReceiver misconfigured or SMTP creds wrongCheck journalctl -u alertmanager -f during a test alert; look for auth failed or connection refused
    Slack posts succeed but look emptyTemplate references missing labelsConfirm the rule sets those labels; templates render empty strings for absent fields
    Duplicate notifications in HA setupCluster not formedcurl /api/v2/status \</td><td>jq .cluster.peers must list all nodes; check 9094 reachability
    Silences disappear after restart--storage.path points at tmpfs or was not persistedVerify /var/lib/alertmanager is on a real disk with correct ownership
    context deadline exceeded talking to PagerDutyOutbound HTTPS blockedAllow egress to events.pagerduty.com:443 on your firewall

    Viewing Logs

    bash
    sudo journalctl -u alertmanager -f

    Fire a synthetic alert for end-to-end testing:

    bash
    curl -XPOST http://127.0.0.1:9093/api/v2/alerts -H 'Content-Type: application/json' -d '[
      {
        "labels": {"alertname": "TestAlert", "severity": "critical", "env": "prod", "service": "demo"},
        "annotations": {"summary": "This is a test from curl"},
        "startsAt": "2026-04-16T12:00:00Z"
      }
    ]'

    You should see it propagate to the configured receiver within group_wait seconds.

    FAQ

    Do I need Alertmanager if Prometheus already has alerting rules?

    Yes. Prometheus evaluates rules and produces alerts, but it has no notion of notification channels, grouping, deduplication, silences, or inhibition. Sending those alerts somewhere useful is entirely Alertmanager's job. The two are designed to be used together.

    How is Alertmanager different from Grafana Alerting?

    Grafana ships with its own alerting engine that can evaluate queries against any data source (Prometheus, Loki, InfluxDB, and more) and send notifications directly. For simple setups, Grafana Alerting is enough. Alertmanager shines when you already have Prometheus-style alert rules versioned in git, need HA deduplication across multiple Prometheus replicas, or want a single notification hub that multiple producers push to. Many teams run both: Grafana for visualisation-driven alerts, Alertmanager for the long-tail of infrastructure rules.

    Can I use Alertmanager with VictoriaMetrics instead of Prometheus?

    Yes. VictoriaMetrics ships a separate component called vmalert that evaluates Prometheus-compatible alerting rules and forwards the resulting alerts to Alertmanager over the same HTTP API Prometheus uses. The Alertmanager config you wrote in this tutorial works unchanged.

    How do I silence every alert during a maintenance window?

    Create a wildcard silence that matches every alert:

    bash
    amtool --alertmanager.url=http://127.0.0.1:9093 silence add \
      alertname=~".+" --duration=1h --comment="Full maintenance"

    The regex .+ matches any non-empty alertname. Expire it immediately once the window ends so you do not silently drop real alerts later.

    Is 2 GB of RAM really enough for Alertmanager?

    For the Alertmanager process itself, 2 GB is generous — it typically uses 50-150 MB even with hundreds of active alerts. The Starter VPS at EUR 7.99/month has headroom for Alertmanager plus Nginx, node_exporter, and a small Prometheus agent. If you want to co-host a full Prometheus retention store and Grafana on the same box, step up to a larger plan.

    How do I handle on-call rotations without paying for PagerDuty?

    Two lightweight options: (1) use an IMAP-based rotation where the PagerDuty receiver is replaced with an email receiver pointing at an alias that changes schedule weekly via a simple cron job; (2) deploy Oncall (LinkedIn's open-source rotation manager) or Grafana OnCall OSS and point an Alertmanager webhook receiver at it. Both give you escalation chains and phone calls without the SaaS bill.

    What happens to in-flight alerts when I restart Alertmanager?

    The notification log (nflog) and active silences persist in /var/lib/alertmanager, so a restart does not duplicate recently-sent notifications and does not forget silences. Alerts currently being evaluated by Prometheus are simply re-pushed on the next evaluation tick (every 15s by default), so a brief Alertmanager restart is effectively invisible.

    Next Steps

    Now that Alertmanager is running, here are sensible ways to build on it:

    • Add Prometheus to the same host — follow our Prometheus on Ubuntu 24.04 guide to complete the metrics pipeline.
    • Layer Grafana on top — our Grafana install tutorial covers dashboards that complement the alerting you just built.
    • Ship logs alongside metrics — Loki pairs with Prometheus labels so log lines and alerts share the same dimensions.
    • Swap Prometheus for long-term storage — when retention gets expensive, VictoriaMetrics is a drop-in backend that keeps your Alertmanager config unchanged.
    • Version the config in git — keep alertmanager.yml, rule files, and templates in a repo with amtool check-config in CI so bad PRs never reach production.
    • Read the upstream docs — the official Alertmanager documentation covers every configuration knob in exhaustive detail, including receivers this tutorial did not touch (Opsgenie, VictorOps, WeChat, Pushover, Telegram).

    Build Your Observability Stack on CloudCore
    >
    Alertmanager is light, but a full metrics-and-logs pipeline adds up. Start on a CloudCore Starter VPS at EUR 7.99/month, scale up as your retention grows, and keep everything on one predictable monthly bill — no per-host monitoring fees, no per-user alerting surcharges, no surprise egress charges.
    >
    - 2 vCPU, 2 GB RAM, 50 GB NVMe
    - Ubuntu 24.04 LTS pre-installed
    - Unmetered bandwidth
    - Deploy in under 60 seconds
    >
    Launch a Starter VPS and follow this tutorial on real hardware.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket