Skip to main content
COSMICBYTEZLABS
NewsSecurityHOWTOsToolsTraining
StudyProjectsNewsletterHire MeAbout
Subscribe

Press Enter to search or Esc to close

News
Security
HOWTOs
Tools
Training
Study
Projects
Newsletter
Hire Me
About
RSS Feed
Reading List
Subscribe

Stay in the Loop

Get the latest security alerts, tutorials, and tech insights delivered to your inbox.

Subscribe NowFree forever. No spam.
COSMICBYTEZLABS

Your trusted source for IT intelligence, cybersecurity insights, and hands-on technical guides.

3005+ Articles
169+ Guides

CONTENT

  • Latest News
  • Security Alerts
  • HOWTOs
  • Checklists
  • Projects
  • Exam Prep

RESOURCES

  • Search
  • Browse Tags
  • Newsletter Archive
  • Reading List
  • RSS Feed

COMPANY

  • About Us
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CosmicBytez Labs. All rights reserved.

System Status: Operational
  1. Home
  2. Projects
  3. Zabbix Monitoring Stack: Self-Hosted Infrastructure Health & Alerting
Zabbix Monitoring Stack: Self-Hosted Infrastructure Health & Alerting
PROJECTIntermediate

Zabbix Monitoring Stack: Self-Hosted Infrastructure Health & Alerting

Deploy Zabbix 7.0 in Docker to monitor hosts, containers, and network gear, then wire trigger-based alerts straight into Discord.

Dylan H.

Projects

September 22, 2026
5 min read
3-5 hours

Tools & Technologies

Zabbix Server 7.0 LTSZabbix Agent 2Docker ComposePostgreSQL 16

Overview

Prometheus and Grafana are great for time-series metrics and dashboards, but they leave you to build alerting logic and host inventory yourself. Zabbix takes the opposite approach: it ships as a single opinionated platform with agent-based polling, a built-in trigger/action engine, host inventory, network discovery, and alerting — all configured through one web frontend, no separate rules engine required.

This project deploys a complete Zabbix 7.0 LTS stack in Docker (the current long-term-support line, patched through 7.0.19), monitors a mix of Linux hosts and Docker containers with Zabbix Agent 2, adds an SNMP-polled network device, and routes trigger-based alerts to a Discord channel. By the end you'll have a single pane of glass for host health, service availability, and infrastructure alerting that runs entirely on your own hardware.

What you'll build:

  • Zabbix server + web frontend + PostgreSQL 16 in Docker Compose
  • Zabbix Agent 2 monitoring the Docker host and its containers
  • A remote Linux host monitored over active checks
  • An SNMP-polled network device (router/switch/UPS)
  • Trigger-based Discord alerting via a custom webhook media type

Architecture

┌────────────────────────────────────────────────┐
│              Monitoring Host (Docker)           │
│                                                  │
│  ┌────────────┐   ┌────────────┐  ┌───────────┐│
│  │  zabbix-web │◄─►│zabbix-server│◄─►│ postgres ││
│  │  (nginx)    │   │   :10051    │  │   :5432  ││
│  │   :8080     │   └──────┬─────┘  └───────────┘│
│  └────────────┘          │                      │
└───────────────────────────┼──────────────────────┘
                             │ active/passive checks
              ┌──────────────┼──────────────┐
              ▼               ▼              ▼
      ┌───────────────┐ ┌──────────┐ ┌───────────────┐
      │ Docker host   │ │ Linux VM │ │ SNMP device    │
      │ Zabbix Agent 2│ │ Agent 2  │ │ (switch/UPS)   │
      │ + containers  │ │          │ │ no agent needed│
      └───────────────┘ └──────────┘ └───────────────┘
                             │
                             ▼
                     ┌───────────────┐
                     │ Discord Webhook│
                     │ (trigger action)│
                     └───────────────┘

The server component evaluates incoming item data against triggers and fires actions — in this build, an HTTP webhook media type that posts formatted alerts to Discord. Agents run in active mode by default in this guide, meaning each host pulls its own check configuration from the server and pushes data back, which works cleanly through NAT and firewalls without opening inbound ports to every monitored host.


Prerequisites

  • Docker Engine 24+ and Docker Compose v2
  • 2 GB RAM minimum for the server stack (4 GB recommended once dashboards and history grow)
  • A Linux host or VM to monitor remotely (Agent 2 install)
  • Optional: an SNMP-capable switch, router, or UPS on the same network
  • A Discord server with permission to create webhooks

Step 1 — Docker Compose Stack

Create a project directory and a .env file for credentials:

mkdir zabbix-stack && cd zabbix-stack
cat > .env <<'EOF'
POSTGRES_USER=zabbix
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD
POSTGRES_DB=zabbix
TZ=America/Edmonton
EOF

Create docker-compose.yml:

services:
  postgres-server:
    image: postgres:16-alpine
    container_name: zabbix-postgres
    restart: unless-stopped
    env_file: .env
    volumes:
      - zbx-postgres-data:/var/lib/postgresql/data
 
  zabbix-server:
    image: zabbix/zabbix-server-pgsql:7.0-ubuntu-latest
    container_name: zabbix-server
    restart: unless-stopped
    env_file: .env
    environment:
      - DB_SERVER_HOST=postgres-server
    ports:
      - "10051:10051"
    volumes:
      - zbx-server-data:/var/lib/zabbix
    depends_on:
      - postgres-server
 
  zabbix-web:
    image: zabbix/zabbix-web-nginx-pgsql:7.0-ubuntu-latest
    container_name: zabbix-web
    restart: unless-stopped
    env_file: .env
    environment:
      - DB_SERVER_HOST=postgres-server
      - ZBX_SERVER_HOST=zabbix-server
      - PHP_TZ=America/Edmonton
    ports:
      - "8080:8080"
    depends_on:
      - zabbix-server
 
  zabbix-agent:
    image: zabbix/zabbix-agent2:7.0-ubuntu-latest
    container_name: zabbix-agent
    restart: unless-stopped
    env_file: .env
    environment:
      - ZBX_HOSTNAME=docker-host
      - ZBX_SERVER_HOST=zabbix-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /:/rootfs:ro
    group_add:
      - "988"  # docker group GID on the host — check with `getent group docker`
 
volumes:
  zbx-postgres-data:
  zbx-server-data:

Bring it up:

docker compose up -d
docker compose logs -f zabbix-server

Wait for server #0 started [main process] before continuing. First boot runs the database schema import and takes 1-2 minutes.


Step 2 — Frontend Setup Wizard

Open http://YOUR_HOST:8080. The setup wizard confirms the database connection (pre-filled from environment variables) and creates the default Admin account with password zabbix.

Immediately change the default password: Administration → Users → Admin → change password. The default credential is public knowledge and internet-facing Zabbix frontends running it are routinely scanned.

Once logged in, go to Data collection → Hosts and find the pre-seeded Zabbix server host. It polls 127.0.0.1:10050 for local agent data that doesn't exist in this container layout — either disable it or repoint its interface, otherwise you'll get a permanent "unreachable" alert:

Data collection → Hosts → Zabbix server → Interfaces → remove or leave disabled if you won't monitor the server container itself.


Step 3 — Monitor the Docker Host and Containers

The zabbix-agent container is already running with access to the Docker socket. Register it as a host:

Data collection → Hosts → Create host

  • Host name: docker-host (must match ZBX_HOSTNAME above)
  • Templates: Linux by Zabbix agent and Docker by Zabbix agent 2
  • Interfaces: Agent, zabbix-agent, port 10050 (or leave blank for active-only checks)
  • Host groups: Docker Hosts

Save, then check Monitoring → Latest data, filter by docker-host. Within a minute you should see CPU, memory, filesystem, and per-container metrics (docker.container_info, docker.container_stats) populating.

If data doesn't appear, check the agent log:

docker compose logs zabbix-agent | grep -i "failed\|error"

A common cause is the docker group GID mismatch — confirm it with getent group docker on the host and update group_add in the compose file to match.


Step 4 — Add a Remote Linux Host

On the target Linux machine, install Agent 2 directly (not in Docker):

wget https://cdn.zabbix.com/zabbix/binaries/stable/7.0/latest/zabbix_agent2-7.0-linux-3.0-amd64-static.tar.gz
tar xzf zabbix_agent2-*.tar.gz -C /opt/

Edit /opt/zabbix_agent2/etc/zabbix_agent2.conf:

Server=YOUR_ZABBIX_SERVER_IP
ServerActive=YOUR_ZABBIX_SERVER_IP
Hostname=linux-vm-01

Start it (or install as a systemd service using the package repo instead of the static tarball for production use). In the frontend, create a matching host linux-vm-01, assign the Linux by Zabbix agent template, and set the interface type to Agent (active checks) since this host initiates outbound connections rather than accepting inbound polls.


Step 5 — SNMP Monitoring for Network Devices

Most switches, routers, and UPS units expose SNMP without needing an agent installed. Create a host for one:

Data collection → Hosts → Create host

  • Host name: core-switch-01
  • Interfaces: SNMP, target IP, port 161, SNMP version 2 (or 3 if your gear supports it — prefer v3 with auth+priv for anything beyond a fully trusted LAN)
  • SNMP community: your device's read-only community string (default public should be changed on the device itself)
  • Templates: search for a vendor-matched template, e.g. Generic SNMP as a baseline, or a specific one shipped for your switch/UPS model

Zabbix's built-in template library covers most common network gear. For unsupported devices, use Configuration → Discovery with an SNMP OID walk to build a custom item set from whatever the device exposes.


Step 6 — Discord Alerting via Webhook

Create a Discord webhook: Server Settings → Integrations → Webhooks → New Webhook, copy the URL.

In Zabbix: Alerts → Media types → Import, or build one manually as a Webhook media type with this JavaScript body (paste into the media type's Script field):

try {
  var params = JSON.parse(value),
      req = new HttpRequest(),
      payload = {
        content: null,
        embeds: [{
          title: params.subject,
          description: params.message,
          color: params.status === 'PROBLEM' ? 15548997 : 5763719
        }]
      };
 
  req.addHeader('Content-Type: application/json');
  req.post(params.webhook_url, JSON.stringify(payload));
 
  if (req.getStatus() >= 300) {
    throw 'Discord webhook returned status ' + req.getStatus();
  }
  return 'OK';
} catch (error) {
  Zabbix.log(4, '[Discord webhook] ' + error);
  throw 'Discord notification failed: ' + error;
}

Add parameters webhook_url, subject, message, status mapped to Zabbix macros ({ALERT.SUBJECT}, {ALERT.MESSAGE}, {EVENT.NAME} etc. — customize per your trigger action). Then:

  1. Users → Admin → Media — add the Discord media type with your webhook URL
  2. Alerts → Actions → Trigger actions — create a new action, condition Trigger severity >= Average, operation "Send message" to the Admin user via the Discord media type

Testing Your Setup

Force a test problem to confirm the pipeline end to end:

# Fill disk temporarily on the monitored host to cross a threshold trigger
fallocate -l 5G /tmp/zbx-test-file

Watch Monitoring → Problems in the frontend — a disk space trigger should appear within one polling interval (default 60s for most templated items). Confirm the Discord message arrives in the target channel, then clean up:

rm /tmp/zbx-test-file

The problem should auto-resolve in Zabbix and (if you configured a recovery message) post a second Discord message confirming resolution.

Also verify agent connectivity directly, bypassing the frontend:

docker exec zabbix-server zabbix_get -s docker-host -k agent.ping
# Expect: 1

Deployment and Hardening

  • Put the frontend behind a reverse proxy with TLS (Traefik, Caddy, Nginx) — don't expose port 8080 directly to the internet
  • Restrict frontend access to your management VLAN or VPN; Zabbix's frontend has historically been a target for CVEs (SQL injection, auth bypass) — keep it patched and firewalled regardless
  • Back up the PostgreSQL volume on a schedule — host configuration, templates, and history all live there:
    docker exec zabbix-postgres pg_dump -U zabbix zabbix | gzip > zabbix-backup-$(date +%F).sql.gz
  • Rotate the default SNMP community string and prefer SNMPv3 for anything beyond a trusted LAN segment
  • Use Zabbix API tokens, not user passwords, for any automation or scripts that query the API — generate under Users → API tokens

Extensions and Next Steps

Auto-discovery: Configure a network discovery rule (Data collection → Discovery) to sweep a subnet and auto-register hosts responding to ICMP/SNMP, reducing manual host creation as your homelab grows.

Low-level discovery (LLD): Extend the Docker template with custom LLD rules to auto-discover containers by label, so new containers get monitored the moment they start without manual host edits.

Grafana integration: Zabbix's history data can feed Grafana via the community Zabbix data source plugin if you want richer dashboards layered on top of Zabbix's own alerting — pairing the Prometheus/Grafana stack for metrics with Zabbix for agent-based inventory and alerting is a common hybrid pattern.

Maintenance windows via automation: Script Zabbix maintenance windows around planned deploys or reboots using the API, so trigger actions don't fire false alerts during expected downtime — useful if you're already scripting container recreates or patch cycles elsewhere in your stack.

PDF reporting: Zabbix 6.4+ supports native scheduled PDF reports of dashboards for stakeholders who want a weekly summary without frontend access — requires the optional zabbix-web-service container alongside the core stack.

#monitoring#zabbix#observability#homelab#alerting#docker#snmp

Related Articles

Build a Production Monitoring Stack with Prometheus and Grafana

Deploy a full observability stack — Prometheus metrics collection, Grafana dashboards, AlertManager notifications, and three exporters — all containerized...

8 min read

Runtime Security Monitoring with Falco: Detect Container

Deploy Falco on a Docker host to monitor container syscalls at the kernel level, write custom homelab detection rules, and route real-time alerts through.

12 min read

Building a Wazuh XDR + SIEM Homelab

Deploy a full Wazuh stack in Docker to gain host-based intrusion detection, file integrity monitoring, vulnerability scanning, and active response across your…

14 min read
Back to all Projects