zabbix-enterprise-monitoring-guide

Installation

This chapter describes the installation of a production-ready Zabbix monitoring environment.

The reference architecture uses:

The exact package names and repository paths may differ between operating system and Zabbix versions.

Before installation, verify the currently supported operating systems, database platforms and package repositories for the selected Zabbix release.


Installation Architecture

The basic deployment described in this chapter uses a single Linux server.

                    Administrator
                          │
                          ▼
                    Web Browser
                          │
                       HTTPS
                          │
                          ▼
                   Nginx Frontend
                          │
                          ▼
                   Zabbix Frontend
                          │
                          ▼
                    PostgreSQL
                          ▲
                          │
                    Zabbix Server
                          │
                          ▼
                  Monitored Systems

For smaller environments, the following components may run on the same virtual machine:

For larger deployments, the database and frontend may be separated.


System Requirements

The required resources depend on:

A small deployment may start with:

Resource Recommended minimum
CPU 2 vCPU
Memory 4 GB RAM
Storage 40 GB SSD
Network 1 Gbit/s virtual or physical interface

A more practical production baseline is:

Resource Recommended baseline
CPU 4 vCPU
Memory 8 GB RAM
Storage 80–150 GB SSD
Network 1 Gbit/s
Backup External database and configuration backup

Storage should be increased according to history retention and collected values per second.


Example server parameters:

Hostname: ZBX-SRV-01
Operating system: Debian
IP address: 192.168.10.20
Subnet mask: 255.255.255.0
Default gateway: 192.168.10.1
DNS server: 192.168.10.10
Timezone: Europe/Budapest

Recommended DNS records:

zabbix.example.local
monitoring.example.local

For public or remote administrative access, use a valid domain name and trusted TLS certificate.


Pre-Installation Checklist

Before installing Zabbix, verify the following:


Update the Operating System

Update the installed packages before adding the Zabbix repository.

apt update
apt full-upgrade -y

Remove packages that are no longer required:

apt autoremove -y

Verify the operating system version:

cat /etc/os-release

Verify the kernel:

uname -a

A reboot may be required after kernel or system library updates.

reboot

Configure the Hostname

Set the server hostname:

hostnamectl set-hostname ZBX-SRV-01

Verify it:

hostnamectl

Update /etc/hosts:

nano /etc/hosts

Example:

127.0.0.1       localhost
127.0.1.1       ZBX-SRV-01
192.168.10.20   ZBX-SRV-01 zabbix.example.local

Test local resolution:

getent hosts ZBX-SRV-01
getent hosts zabbix.example.local

Configure the Timezone

Set the correct timezone:

timedatectl set-timezone Europe/Budapest

Verify time configuration:

timedatectl

Expected output should confirm:

Time zone: Europe/Budapest
System clock synchronized: yes
NTP service: active

Accurate time synchronization is critical for:


Configure Time Synchronization

Install Chrony:

apt install chrony -y

Enable and start the service:

systemctl enable --now chrony

Verify synchronization:

chronyc tracking

Display configured time sources:

chronyc sources -v

Configure a Static IP Address

The exact configuration method depends on the Debian installation and network stack.

Possible implementations include:

Example using /etc/network/interfaces:

nano /etc/network/interfaces

Example configuration:

auto ens18
iface ens18 inet static
    address 192.168.10.20/24
    gateway 192.168.10.1
    dns-nameservers 192.168.10.10 1.1.1.1

Restart networking carefully:

systemctl restart networking

When connected remotely, changing network configuration may terminate the SSH session.

Verify:

ip address show
ip route show
resolvectl status

Test connectivity:

ping -c 4 192.168.10.1
ping -c 4 1.1.1.1
ping -c 4 deb.debian.org

Install Required Utilities

Install common administrative and troubleshooting packages:

apt install -y \
    curl \
    wget \
    gnupg \
    ca-certificates \
    lsb-release \
    nano \
    vim \
    unzip \
    tar \
    jq \
    net-tools \
    iproute2 \
    dnsutils \
    traceroute \
    tcpdump \
    htop \
    sudo

These tools are useful for:


Configure the Firewall

A host-based firewall should permit only required connections.

Typical inbound ports include:

Port Protocol Purpose
22 TCP SSH administration
80 TCP HTTP redirect or certificate validation
443 TCP Zabbix frontend
10050 TCP Local Zabbix agent passive checks
10051 TCP Zabbix server and proxy communication

The exact rules depend on the architecture.

Install UFW if required:

apt install ufw -y

Set default policies:

ufw default deny incoming
ufw default allow outgoing

Allow SSH from the management network:

ufw allow from 192.168.10.0/24 to any port 22 proto tcp

Allow HTTPS:

ufw allow 443/tcp

Allow HTTP if required:

ufw allow 80/tcp

Allow Zabbix server communication from authorized networks:

ufw allow from 192.168.10.0/24 to any port 10051 proto tcp

Enable the firewall:

ufw enable

Verify the rules:

ufw status verbose

Do not enable firewall rules without confirming that SSH access will remain available.


Install the Zabbix Repository

Download the repository package for the selected operating system and Zabbix release.

Example structure:

wget https://repo.zabbix.com/zabbix/<VERSION>/release/debian/pool/main/z/zabbix-release/zabbix-release_latest_<VERSION>+debian<DEBIAN_VERSION>_all.deb

Install the repository package:

dpkg -i zabbix-release_latest_*.deb

Update package metadata:

apt update

Verify that Zabbix packages are available:

apt-cache policy zabbix-server-pgsql

The repository URL must match:


Install PostgreSQL

Install PostgreSQL:

apt install postgresql postgresql-contrib -y

Enable and start PostgreSQL:

systemctl enable --now postgresql

Verify service status:

systemctl status postgresql

Check the installed version:

psql --version

List PostgreSQL clusters:

pg_lsclusters

Create the Zabbix Database User

Switch to the PostgreSQL administrative user:

sudo -u postgres psql

Create the Zabbix database user:

CREATE USER zabbix WITH PASSWORD 'CHANGE_THIS_STRONG_PASSWORD';

Create the database:

CREATE DATABASE zabbix OWNER zabbix;

Exit PostgreSQL:

\q

Use a strong, unique password.

Do not reuse:


Verify Database Access

Test authentication:

psql -h 127.0.0.1 -U zabbix -d zabbix

Enter the database password when prompted.

Verify the current connection:

\conninfo

Exit:

\q

If authentication fails, review:

/etc/postgresql/<VERSION>/main/pg_hba.conf

Common local authentication methods include:

scram-sha-256
md5
peer

After modifying PostgreSQL configuration:

systemctl restart postgresql

Install Zabbix Server and Frontend Packages

Install the required Zabbix components:

apt install -y \
    zabbix-server-pgsql \
    zabbix-frontend-php \
    php8.2-pgsql \
    zabbix-nginx-conf \
    zabbix-sql-scripts \
    zabbix-agent2

Package names may differ depending on:

Verify installed packages:

dpkg -l | grep zabbix

Import the Initial Database Schema

Locate the PostgreSQL schema file:

find /usr/share/zabbix-sql-scripts -type f | grep server.sql

The file may be compressed.

Example import command:

zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz \
    | sudo -u zabbix psql zabbix

Alternatively:

zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz \
    | psql -h 127.0.0.1 -U zabbix -d zabbix

The import may take several minutes depending on system performance.

Verify database tables:

sudo -u postgres psql -d zabbix -c "\dt"

Verify the table count:

sudo -u postgres psql -d zabbix -tAc \
"SELECT count(*) FROM information_schema.tables WHERE table_schema='public';"

A successful import creates numerous Zabbix tables.


Configure the Zabbix Server

Edit the server configuration:

nano /etc/zabbix/zabbix_server.conf

Configure the database settings:

DBHost=127.0.0.1
DBName=zabbix
DBUser=zabbix
DBPassword=CHANGE_THIS_STRONG_PASSWORD

Recommended initial settings may include:

LogFile=/var/log/zabbix/zabbix_server.log
LogFileSize=0
PidFile=/run/zabbix/zabbix_server.pid
SocketDir=/run/zabbix

Do not change performance-related process counts before establishing a baseline.

Examples of settings that may require later tuning:

StartPollers=
StartPreprocessors=
StartTrappers=
StartPingers=
StartDiscoverers=
CacheSize=
HistoryCacheSize=
HistoryIndexCacheSize=
TrendCacheSize=
ValueCacheSize=
Timeout=

Premature tuning can make troubleshooting more difficult.


Protect Database Credentials

Restrict access to the Zabbix server configuration:

chown root:zabbix /etc/zabbix/zabbix_server.conf
chmod 640 /etc/zabbix/zabbix_server.conf

Verify:

ls -l /etc/zabbix/zabbix_server.conf

Expected permissions:

-rw-r----- root zabbix

The configuration file contains sensitive database credentials and must not be world-readable.


Configure Nginx

Edit the Zabbix Nginx configuration:

nano /etc/zabbix/nginx.conf

Configure the listening port and hostname:

listen 80;
server_name zabbix.example.local;

Example configuration:

server {
    listen 80;
    server_name zabbix.example.local;

    root /usr/share/zabbix;

    index index.php;

    location = /favicon.ico {
        log_not_found off;
    }

    location / {
        try_files $uri $uri/ =404;
    }

    location /assets {
        access_log off;
        expires 10d;
    }

    location ~ /\.ht {
        deny all;
    }

    location ~ /(api\/|conf[^\.]|include|locale) {
        deny all;
        return 404;
    }

    location /vendor {
        deny all;
        return 404;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_pass unix:/run/php/zabbix.sock;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;

        fastcgi_param DOCUMENT_ROOT /usr/share/zabbix;
        fastcgi_param SCRIPT_FILENAME /usr/share/zabbix$fastcgi_script_name;
        fastcgi_param PATH_TRANSLATED /usr/share/zabbix$fastcgi_script_name;

        include fastcgi_params;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;

        fastcgi_intercept_errors on;
        fastcgi_ignore_client_abort off;
        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
    }
}

Test the Nginx configuration:

nginx -t

Configure PHP-FPM

Locate the Zabbix PHP-FPM configuration:

ls -l /etc/zabbix/php-fpm.conf

Edit it:

nano /etc/zabbix/php-fpm.conf

Set the timezone:

php_value[date.timezone] = Europe/Budapest

Recommended PHP values may include:

php_value[max_execution_time] = 300
php_value[memory_limit] = 256M
php_value[post_max_size] = 32M
php_value[upload_max_filesize] = 16M
php_value[max_input_time] = 300
php_value[session.auto_start] = 0
php_value[mbstring.func_overload] = 0
php_value[always_populate_raw_post_data] = -1

Restart PHP-FPM after changes.

The exact service name depends on the installed PHP version.

Example:

systemctl restart php8.2-fpm

Start Zabbix Services

Enable and start the required services:

systemctl enable --now \
    zabbix-server \
    zabbix-agent2 \
    nginx \
    php8.2-fpm

Restart all components:

systemctl restart \
    zabbix-server \
    zabbix-agent2 \
    nginx \
    php8.2-fpm

Check service status:

systemctl status zabbix-server
systemctl status zabbix-agent2
systemctl status nginx
systemctl status php8.2-fpm

Verify Listening Ports

Check active listening sockets:

ss -tulpn

Expected ports may include:

TCP 80       Nginx
TCP 443      Nginx after HTTPS configuration
TCP 10050    Zabbix Agent 2
TCP 10051    Zabbix Server
TCP 5432     PostgreSQL, usually local only
TCP 22       SSH

Filter Zabbix ports:

ss -lntp | grep -E '10050|10051'

Verify Nginx:

ss -lntp | grep -E ':80|:443'

Review Zabbix Server Logs

Display the latest server log entries:

tail -n 100 /var/log/zabbix/zabbix_server.log

Follow the log in real time:

tail -f /var/log/zabbix/zabbix_server.log

Using journalctl:

journalctl -u zabbix-server -n 100 --no-pager

Typical errors include:


Review Nginx and PHP Logs

Check Nginx errors:

tail -n 100 /var/log/nginx/error.log

Check access logs:

tail -n 100 /var/log/nginx/access.log

Check PHP-FPM:

journalctl -u php8.2-fpm -n 100 --no-pager

Common frontend problems include:


Complete the Web Installation

Open the Zabbix frontend:

http://zabbix.example.local

The installation wizard verifies:

During database configuration, enter:

Database type: PostgreSQL
Database host: 127.0.0.1
Database port: 5432
Database name: zabbix
Database user: zabbix
Database password: configured database password

Set the Zabbix server name:

SARABEL Monitoring

Complete the wizard.


Default Frontend Login

The default Zabbix administrative account is commonly:

Username: Admin
Password: zabbix

Usernames may be case-sensitive.

Immediately after the first login:

  1. change the default administrator password;
  2. create a named administrative user;
  3. avoid using the default account for normal administration;
  4. review frontend permissions;
  5. configure authentication security.

Do not leave the default password unchanged.


Create a Named Administrator Account

Navigate to:

Users
→ Users
→ Create user

Example:

Username: joco.admin
Name: József
Surname: Takács
Role: Super admin role
User group: Zabbix administrators

Set a strong password.

After verifying the new account, the default Admin account should be disabled or protected according to organizational policy.


Configure HTTPS

The Zabbix frontend should use HTTPS.

Possible certificate sources include:

Install Certbot for Nginx:

apt install certbot python3-certbot-nginx -y

Request a certificate:

certbot --nginx -d zabbix.example.com

Certbot can automatically:

Test renewal:

certbot renew --dry-run

Check the renewal timer:

systemctl status certbot.timer

Public certificates require:


Example Manual HTTPS Configuration

Example Nginx configuration:

server {
    listen 80;
    server_name zabbix.example.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name zabbix.example.com;

    ssl_certificate /etc/letsencrypt/live/zabbix.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/zabbix.example.com/privkey.pem;

    root /usr/share/zabbix;
    index index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_pass unix:/run/php/zabbix.sock;
        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME \
            /usr/share/zabbix$fastcgi_script_name;
    }
}

Test and reload Nginx:

nginx -t
systemctl reload nginx

Configure Zabbix Agent 2 on the Server

Edit the Agent 2 configuration:

nano /etc/zabbix/zabbix_agent2.conf

Configure the server addresses:

Server=127.0.0.1,192.168.10.20
ServerActive=127.0.0.1
Hostname=ZBX-SRV-01

Important:

Hostname=

must match the host name created in the Zabbix frontend when active checks are used.

Restart the agent:

systemctl restart zabbix-agent2

Enable it:

systemctl enable zabbix-agent2

Check status:

systemctl status zabbix-agent2

Test the Local Agent

Install zabbix-get:

apt install zabbix-get -y

Test agent availability:

zabbix_get -s 127.0.0.1 -k agent.ping

Expected output:

1

Test hostname:

zabbix_get -s 127.0.0.1 -k system.hostname

Test system uptime:

zabbix_get -s 127.0.0.1 -k system.uptime

Test CPU count:

zabbix_get -s 127.0.0.1 -k system.cpu.num

Test memory:

zabbix_get -s 127.0.0.1 -k vm.memory.size[total]

Add the Zabbix Server as a Monitored Host

In the frontend, navigate to:

Data collection
→ Hosts
→ Create host

Configure:

Host name: ZBX-SRV-01
Visible name: Zabbix Server
Host groups:
- Zabbix servers
- Linux servers

Add an agent interface:

IP address: 127.0.0.1
Port: 10050

Assign templates:

Linux by Zabbix agent
Zabbix server health

Template names may differ between versions.

Save the host.


Verify Data Collection

Navigate to:

Monitoring
→ Latest data

Filter by:

Host: ZBX-SRV-01

Verify that values are received for:

If values are missing, verify:


Configure Database Backup

A monitoring platform must have a tested database backup.

Create a backup directory:

mkdir -p /var/backups/zabbix
chown postgres:postgres /var/backups/zabbix
chmod 700 /var/backups/zabbix

Create a manual backup:

sudo -u postgres pg_dump \
    -Fc \
    -d zabbix \
    -f /var/backups/zabbix/zabbix_$(date +%F_%H-%M).dump

List backup files:

ls -lh /var/backups/zabbix

Verify the backup:

sudo -u postgres pg_restore \
    --list \
    /var/backups/zabbix/zabbix_YYYY-MM-DD_HH-MM.dump

A backup that has never been tested is not a verified backup.


Automated Database Backup Script

Create a backup script:

nano /usr/local/sbin/zabbix-db-backup.sh

Example:

#!/bin/bash

set -euo pipefail

BACKUP_DIR="/var/backups/zabbix"
DATABASE="zabbix"
RETENTION_DAYS="14"
TIMESTAMP="$(date +%F_%H-%M-%S)"
BACKUP_FILE="${BACKUP_DIR}/${DATABASE}_${TIMESTAMP}.dump"

mkdir -p "${BACKUP_DIR}"

sudo -u postgres pg_dump \
    -Fc \
    -d "${DATABASE}" \
    -f "${BACKUP_FILE}"

find "${BACKUP_DIR}" \
    -type f \
    -name "${DATABASE}_*.dump" \
    -mtime +"${RETENTION_DAYS}" \
    -delete

echo "Backup completed: ${BACKUP_FILE}"

Make the script executable:

chmod 750 /usr/local/sbin/zabbix-db-backup.sh

Test it:

/usr/local/sbin/zabbix-db-backup.sh

Schedule the Backup

Edit root crontab:

crontab -e

Example daily backup at 02:00:

0 2 * * * /usr/local/sbin/zabbix-db-backup.sh >> /var/log/zabbix-db-backup.log 2>&1

Verify scheduled jobs:

crontab -l

Database backups should also be copied to:

Keeping backups only on the Zabbix server does not protect against complete server failure.


Back Up Configuration Files

Important configuration paths include:

/etc/zabbix/
/etc/nginx/
/etc/php/
/etc/postgresql/
/etc/letsencrypt/
/usr/lib/zabbix/
/usr/local/share/zabbix/

Example archive:

tar -czf /var/backups/zabbix/zabbix-config_$(date +%F).tar.gz \
    /etc/zabbix \
    /etc/nginx \
    /etc/postgresql

Certificate directories may require separate handling due to sensitive private keys.


Test Database Restoration

Create a temporary restore database:

sudo -u postgres createdb zabbix_restore_test

Restore the backup:

sudo -u postgres pg_restore \
    -d zabbix_restore_test \
    /var/backups/zabbix/zabbix_YYYY-MM-DD_HH-MM.dump

Verify the restored tables:

sudo -u postgres psql \
    -d zabbix_restore_test \
    -c "SELECT count(*) FROM hosts;"

Delete the test database:

sudo -u postgres dropdb zabbix_restore_test

Restore tests should be performed regularly.


Configure Log Rotation

Zabbix packages normally install logrotate configuration.

Verify:

cat /etc/logrotate.d/zabbix-server
cat /etc/logrotate.d/zabbix-agent2

Test logrotate configuration:

logrotate -d /etc/logrotate.conf

Check log file sizes:

du -sh /var/log/zabbix
du -sh /var/log/nginx
du -sh /var/log/postgresql

Uncontrolled log growth can exhaust the root filesystem.


Secure SSH Access

Recommended SSH controls include:

Edit SSH configuration:

nano /etc/ssh/sshd_config

Example settings:

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers monitoringadmin

Validate the configuration:

sshd -t

Restart SSH:

systemctl restart ssh

Do not disable password authentication before confirming that key-based login works.


Create an Administrative User

Create a named administrative account:

adduser monitoringadmin

Grant sudo access:

usermod -aG sudo monitoringadmin

Verify:

id monitoringadmin

Configure SSH keys:

mkdir -p /home/monitoringadmin/.ssh
nano /home/monitoringadmin/.ssh/authorized_keys

Set permissions:

chown -R monitoringadmin:monitoringadmin \
    /home/monitoringadmin/.ssh

chmod 700 /home/monitoringadmin/.ssh
chmod 600 /home/monitoringadmin/.ssh/authorized_keys

Disable Unnecessary Services

List enabled services:

systemctl list-unit-files --state=enabled

List listening ports:

ss -tulpn

Disable unused services only after confirming their purpose.

Example:

systemctl disable --now <service-name>

Do not disable:


Configure Automatic Security Updates

Install unattended upgrades:

apt install unattended-upgrades apt-listchanges -y

Configure:

dpkg-reconfigure unattended-upgrades

Review:

/etc/apt/apt.conf.d/50unattended-upgrades
/etc/apt/apt.conf.d/20auto-upgrades

Automatic upgrades should be aligned with the organization’s change-management policy.

Critical production systems may require:


Verify Database Health

Check PostgreSQL service:

systemctl status postgresql

Check database size:

sudo -u postgres psql -d zabbix -c \
"SELECT pg_size_pretty(pg_database_size('zabbix'));"

Check active sessions:

sudo -u postgres psql -d zabbix -c \
"SELECT count(*) FROM pg_stat_activity;"

Check long-running queries:

sudo -u postgres psql -d zabbix -c "
SELECT
    pid,
    now() - query_start AS duration,
    state,
    query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duration DESC;
"

Verify Zabbix Internal Health

In the frontend, review:

Monitoring
→ Hosts
→ Zabbix Server

Important internal metrics include:

Persistently high process utilization may require:


Installation Validation Commands

Use the following commands for a final system check.

Operating system

hostnamectl
timedatectl
uptime
df -h
free -h

Network

ip address show
ip route show
ss -tulpn
ping -c 4 192.168.10.1

Services

systemctl is-active postgresql
systemctl is-active nginx
systemctl is-active php8.2-fpm
systemctl is-active zabbix-server
systemctl is-active zabbix-agent2

Database

sudo -u postgres psql -d zabbix -c "SELECT version();"

Zabbix Agent

zabbix_get -s 127.0.0.1 -k agent.ping

Web frontend

curl -I http://127.0.0.1

After HTTPS configuration:

curl -I https://zabbix.example.com

Installation Checklist

Operating system

Database

Zabbix components

Web frontend

Security

Monitoring readiness


Common Installation Problems

Zabbix Server Does Not Start

Check:

systemctl status zabbix-server
journalctl -u zabbix-server -n 100 --no-pager
tail -n 100 /var/log/zabbix/zabbix_server.log

Common causes:


Database Connection Failed

Test manually:

psql -h 127.0.0.1 -U zabbix -d zabbix

Verify:

DBHost=
DBName=
DBUser=
DBPassword=

Check PostgreSQL authentication:

cat /etc/postgresql/*/main/pg_hba.conf

Frontend Displays a Blank Page

Check:

tail -n 100 /var/log/nginx/error.log
journalctl -u php8.2-fpm -n 100 --no-pager

Common causes:


Zabbix Agent Is Unreachable

Check:

systemctl status zabbix-agent2
ss -lntp | grep 10050

Test locally:

zabbix_get -s 127.0.0.1 -k agent.ping

Verify:

Server=
ServerActive=
Hostname=

Check the firewall:

ufw status verbose

Hostname Mismatch

Active checks require an exact hostname match.

Agent configuration:

Hostname=ZBX-SRV-01

Frontend host name:

ZBX-SRV-01

These values must match exactly.


Nginx Configuration Test Fails

Run:

nginx -t

Review the reported file and line number.

Common causes:


Production Recommendations

For production use:


Summary

A successful Zabbix installation requires more than installing software packages.

The deployment must include:

After installation, the next step is to create, organize and manage monitored hosts.

Next: Host Management →