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?
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_byflattens the storm; PagerDuty will not. - Silences are cheap and auditable. Before a planned deployment, a single
amtool silence addcommand 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.
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:
ssh root@your-server-ipStep 1: Update System Packages
sudo apt update && sudo apt upgrade -yInstall the utilities we will need along the way:
sudo apt install -y curl wget tar ufwIf the kernel was upgraded, reboot before continuing:
sudo rebootStep 2: Create the alertmanager System User
Run Alertmanager under its own unprivileged user so that the process cannot read unrelated files on the host.
sudo useradd --system --no-create-home --shell /bin/false alertmanagerCreate the directories Alertmanager will use for configuration, binary storage, and state:
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.
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-amd64Install the two binaries: alertmanager is the server, amtool is the companion CLI for managing silences and validating configs.
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/amtoolVerify:
alertmanager --version
amtool --versionExpected output:
alertmanager, version 0.27.0 (branch: HEAD, revision: 0aa3c2aad14cff039931923ab16b26b7481783b5)
build user: root@22cd11f671e9
build date: 20240228-11:51:20
go version: go1.21.7Clean up the download:
rm -rf /tmp/alertmanager-${ALERTMANAGER_VERSION}.linux-amd64*Step 4: Create the systemd Unit
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.
sudo systemctl daemon-reloadStep 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.
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:
amtool check-config /etc/alertmanager/alertmanager.ymlExpected output:
Checking '/etc/alertmanager/alertmanager.yml' SUCCESS
Found:
- global config
- route
- 2 inhibit rules
- 6 receivers
- 1 templatesStart the service:
sudo systemctl enable --now alertmanager
sudo systemctl status alertmanagerYou should see active (running). Curl the UI locally to confirm:
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:
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:
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.
sudo apt install -y nginx apache2-utils certbot python3-certbot-nginx
sudo htpasswd -c /etc/nginx/.alertmanager-htpasswd opsuserWrite the vhost:
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:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enableStep 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:
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:
amtool --alertmanager.url=http://127.0.0.1:9093 silence queryExpire a silence:
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/:
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:
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=infoEach node lists all peers including itself — Alertmanager ignores the self entry at startup. Reload and restart on every node:
sudo systemctl daemon-reload
sudo systemctl restart alertmanagerConfirm the cluster is healthy:
curl -s http://127.0.0.1:9093/api/v2/status | jq '.cluster'Expected output:
{
"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
| Problem | Cause | Solution |
|---|---|---|
amtool check-config fails with "no route provided" | Missing top-level route: block | Ensure route: is present with at least a receiver: field |
Prometheus shows Alertmanager DOWN in /status | Wrong port or firewall | Confirm Alertmanager listens on 127.0.0.1:9093 and Prometheus targets match |
No notifications arriving but alerts are firing in /alerts | Receiver misconfigured or SMTP creds wrong | Check journalctl -u alertmanager -f during a test alert; look for auth failed or connection refused |
| Slack posts succeed but look empty | Template references missing labels | Confirm the rule sets those labels; templates render empty strings for absent fields |
| Duplicate notifications in HA setup | Cluster not formed | curl /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 persisted | Verify /var/lib/alertmanager is on a real disk with correct ownership |
context deadline exceeded talking to PagerDuty | Outbound HTTPS blocked | Allow egress to events.pagerduty.com:443 on your firewall |
Viewing Logs
sudo journalctl -u alertmanager -fFire a synthetic alert for end-to-end testing:
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:
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 withamtool check-configin 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.