
Fedora 45 reached general availability in early November 2026, and it brings a few changes that affect anyone installing monitoring software on it. RPM now enforces verified signatures by default, and packages from one repository can no longer be silently replaced by another vendor’s builds. That is good for security. It also breaks a lot of copy-pasted tutorials.
Many Zabbix guides online assume a RHEL-style box with the vendor repository enabled. Zabbix’s own repository lists Red Hat Enterprise Linux, CentOS, Oracle Linux, Ubuntu, Debian, SUSE and Raspbian, and Fedora is not on that list. So the usual “install the release RPM, then dnf install” routine does not apply here. Fedora ships its own zabbix packages, maintained in the distribution repositories, and the version you get depends on the Fedora release.
That raises a practical question. Do you want a monitoring server that tracks the newest Zabbix release, or one that gets patched along with the rest of the OS? On a lab or home server, either works. On a production box, the choice decides how upgrades will go for the next three years.
This guide installs the Zabbix server, web frontend and agent on a clean Fedora 45 host. It uses the distribution packages, PostgreSQL, Apache and SELinux in enforcing mode, because turning SELinux off is the wrong fix. Along the way you get the reasoning behind each step, tuning advice, and a troubleshooting section built from the mistakes that show up again and again.
Before You Start: Versions and Planning
Which Zabbix version will you actually get?
Zabbix 8.0 LTS was released on 5 November 2026. The 7.0 LTS branch is at 7.0.32 and the 7.4 branch at 7.4.16. Fedora’s package versions lag the upstream release and differ per Fedora release. For example, the package page for Fedora 42 listed 7.2.14 and Fedora 41 listed 7.0.21.
Check what your Fedora 45 mirror actually carries before you commit:
sudo dnf upgrade --refresh -y
dnf list --available 'zabbix*' | sort
dnf info zabbix-server-pgsql
Note the version number. Everything below works the same for any current 7.x or 8.x build, but the 8.0 line raises some requirements. Community write-ups of the 8.0 release say the frontend needs PHP 8.2 or newer, and that minimum databases are MariaDB 10.11, MySQL 8.4 or PostgreSQL 15. Fedora 45 comfortably exceeds those, but verify with php -v and psql --version anyway.
If you specifically need an upstream build that Fedora does not package yet, the cleanest route is the official container images or a RHEL-compatible VM. Do not force EL9 vendor RPMs onto Fedora. Library mismatches and the new RPM signature rules will make for a miserable weekend.
Sizing the host
Zabbix is mostly a database workload with a polling engine in front of it. Rough starting points:
| Monitored scale | vCPU | RAM | Disk |
|---|---|---|---|
| Lab, up to 50 hosts | 2 | 4 GB | 40 GB SSD |
| Small production, 200 hosts | 4 | 8 GB | 100 GB SSD/NVMe |
| Mid-size, 1000+ hosts | 8+ | 16 to 32 GB | NVMe, separate DB volume |
The metric that matters is NVPS, new values per second. A box polling 300 hosts at 60-second intervals with 100 items each produces about 500 NVPS. That is easy on modern hardware, but history tables grow fast. Plan disk by retention, not by host count.
Prerequisites checklist
- A fresh Fedora 45 Server or minimal install, fully updated.
- A static IP or a stable DHCP reservation.
- A resolvable hostname, because agents and TLS both depend on it.
- Working time sync. Zabbix graphs and triggers go strange with clock drift.
- Root or sudo access.
Set hostname and time first:
sudo hostnamectl set-hostname zbx01.example.com
sudo timedatectl set-timezone Asia/Jakarta
sudo systemctl enable --now chronyd
chronyc tracking
Use your own timezone. Keeping the server in the timezone your team reads graphs in avoids confusing “why is the alert two hours off” conversations. The frontend timezone is configured separately later.
Step 1: Install and Initialize PostgreSQL
PostgreSQL is the better database choice for most new Zabbix deployments. It handles concurrent writes cleanly, and it pairs well with TimescaleDB if you scale later. MariaDB works too, but this guide sticks to one stack to stay precise.
sudo dnf install -y postgresql-server postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql
Fedora does not initialize the data directory automatically, which is the first place many people stall. If systemctl start postgresql fails with “directory is missing or empty,” you skipped --initdb.
Switch to password authentication over TCP
Zabbix server connects as a database user. Fedora’s default pg_hba.conf uses ident for local TCP connections, which fails for a service account. Open the file:
sudo nano /var/lib/pgsql/data/pg_hba.conf
Make sure the host lines for loopback read:
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256
Then confirm password encryption is the modern default and reload:
sudo -u postgres psql -c "SHOW password_encryption;"
sudo systemctl reload postgresql
It should return scram-sha-256. Avoid md5 on a new build.
Create the Zabbix database and user
sudo -u postgres createuser --pwprompt zabbix
sudo -u postgres createdb -O zabbix -E Unicode -T template0 zabbix
Choose a long random password and store it in your password manager. Generating one is easy:
openssl rand -base64 24
The -T template0 flag matters. It avoids encoding conflicts if the template database was created with a different locale.
Step 2: Install the Zabbix Server, Frontend and Agent
Install the packages from Fedora’s repositories:
sudo dnf install -y zabbix-server-pgsql zabbix-web-pgsql zabbix-agent2 httpd
Package naming can shift between Fedora releases, so if dnf says something is missing, search rather than guess:
dnf search zabbix | grep -E 'server|web|agent|apache|nginx'
You may see separate configuration packages for the web server, such as zabbix-apache-conf or zabbix-nginx-conf. If the search shows them, install the one matching your web server. Then find where things landed:
rpm -ql zabbix-server-pgsql | grep -iE 'sql|conf|service'
rpm -ql zabbix-web-pgsql | grep -iE 'conf|httpd|nginx' | head -20
That rpm -ql habit is worth keeping. Documentation goes stale quickly, but the package manifest never lies.
Why agent2?
Agent 2 is the newer Go-based agent, with plugin support and better concurrency for checks. For a new deployment it is the sensible default. The classic zabbix-agent still works and uses slightly less memory on tiny devices. Pick one per host. Running both causes a port 10050 conflict.
Step 3: Import the Initial Schema
This step is the one people most often get wrong, and the error messages are unhelpful when they do.
Find the schema file your package installed:
rpm -ql zabbix-server-pgsql | grep -iE 'server\.sql|create'
The path is typically somewhere under /usr/share/zabbix-sql-scripts/ or /usr/share/doc/zabbix-server-pgsql*/. Once you have it (adjust the path below), import:
zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | \
psql -h 127.0.0.1 -U zabbix -d zabbix
If your file is not gzipped, use cat instead of zcat. Enter the password you created. The import takes anywhere from 30 seconds to a couple of minutes and prints a lot of CREATE TABLE and INSERT lines.
Using -h 127.0.0.1 forces TCP, so it uses the scram-sha-256 rule you set. Without it, psql tries a Unix socket and peer authentication fails because your shell user is not named zabbix.
Verify the import:
psql -h 127.0.0.1 -U zabbix -d zabbix -c "\dt" | head
psql -h 127.0.0.1 -U zabbix -d zabbix -c "SELECT COUNT(*) FROM users;"
You should see tables listed and at least one user, the default Admin.
Step 4: Configure the Zabbix Server
Open the main config:
sudo nano /etc/zabbix/zabbix_server.conf
Set the database parameters:
DBHost=127.0.0.1
DBName=zabbix
DBUser=zabbix
DBPassword=YourStrongPasswordHere
Leave the rest alone for now. Defaults are conservative, and tuning blind is how people create new problems. Tuning comes later, with evidence.
Lock down the file, since it holds a credential:
sudo chown root:zabbix /etc/zabbix/zabbix_server.conf
sudo chmod 640 /etc/zabbix/zabbix_server.conf
Start the services:
sudo systemctl enable --now zabbix-server zabbix-agent2 httpd php-fpm
sudo systemctl status zabbix-server --no-pager
Then watch the log for a minute:
sudo tail -f /var/log/zabbix/zabbix_server.log
A healthy start shows the server reporting its version, loading the config cache, and starting poller processes. Database connection errors appear right at the top, so you will spot them quickly.
Step 5: Open the Firewall
Fedora Server runs firewalld by default. Allow web traffic, and the Zabbix trapper port if remote agents will report in:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-port=10051/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
Port 10051 is for the server (active agents and proxies connect to it). Port 10050 is for the agent, opened on monitored hosts only when the server polls them in passive mode.
A better habit in production is to restrict that port by source address using a rich rule:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.20.0/24" port port="10051" protocol="tcp" accept'
Exposing 10051 to the whole internet is a classic mistake. Anyone can then send junk to your trapper.
Step 6: Handle SELinux the Right Way
Fedora ships SELinux in enforcing mode, and it will block Zabbix in a few specific ways. The lazy fix is setenforce 0. Do not do it. The correct fix takes about two minutes.
Check the mode:
getenforce
Allow Apache and PHP to reach the database over the network, and let the Zabbix daemons connect outward:
sudo setsebool -P httpd_can_network_connect_db 1
sudo setsebool -P httpd_can_network_connect 1
sudo setsebool -P zabbix_can_network 1
The first lets the frontend talk to PostgreSQL. The second lets it contact the Zabbix server (used for the “Zabbix server is running” status check). The third lets the server daemon make outbound network connections, which many checks need.
If something is still blocked, look at the actual denials:
sudo ausearch -m avc -ts recent
sudo dnf install -y setroubleshoot-server
sudo sealert -a /var/log/audit/audit.log | less
For a persistent custom denial, generate a minimal local policy:
sudo ausearch -m avc -ts recent | audit2allow -M zabbix_local
sudo semodule -i zabbix_local.pp
Read the generated .te file before loading it. Blindly accepting audit2allow output defeats the point of SELinux.
Step 7: Finish Setup in the Web Installer
Browse to http://your-server-ip/zabbix. If the page returns the Apache test page instead, check the config path:
ls /etc/httpd/conf.d/ | grep -i zabbix
sudo apachectl configtest
The installer walks through these screens:
- Language selection.
- Prerequisite check. Every row should be OK. If PHP settings fail, see the PHP section below.
- Database connection: type PostgreSQL, host
127.0.0.1, port5432, databasezabbix, userzabbix, plus your password. Leave TLS unchecked for a local connection. - Server details: host
localhost, port10051, and a descriptive name. - Timezone and theme.
- Confirmation, which writes
/etc/zabbix/web/zabbix.conf.php.
Log in with the default credentials, username Admin and password zabbix. Change that password immediately. This is the most exploited default on the internet, and no amount of firewall tuning rescues you if it stays.
Go to Users → Users → Admin → Change password. Then, while you are there, create a separate named admin account for daily use and consider disabling the shared Admin account.
PHP Settings That the Frontend Expects
If the installer complains about PHP values, edit the pool or ini file. Under Fedora the Zabbix package normally drops its own settings, which you can inspect:
grep -rn "post_max_size\|max_execution_time\|max_input_time" /etc/php-fpm.d/ /etc/php.ini 2>/dev/null
Zabbix expects values along these lines:
post_max_size = 16M
max_execution_time = 300
max_input_time = 300
memory_limit = 128M
date.timezone = Asia/Jakarta
Apply changes with:
sudo systemctl restart php-fpm httpd
A larger memory_limit helps on big dashboards with many widgets. If large reports time out, raise max_execution_time before blaming the database.
Installing and Configuring the Agent
The server host should monitor itself first. It gives you a sanity check and a baseline.
Edit the agent 2 config:
sudo nano /etc/zabbix/zabbix_agent2.conf
Server=127.0.0.1
ServerActive=127.0.0.1
Hostname=zbx01.example.com
The Hostname value must match, character for character, the host name you create in the frontend. For active checks, this is the number one reason an agent “connects but shows no data.”
Restart and test:
sudo systemctl restart zabbix-agent2
sudo zabbix_agent2 -t agent.ping
sudo zabbix_agent2 -t system.cpu.load[all,avg1]
In the frontend, go to Data collection → Hosts. The default “Zabbix server” host is already there. Check its Availability icon, and attach the “Linux by Zabbix agent” template if it isn’t linked.
Rolling out to other servers
On a remote Fedora, RHEL-family or Debian host, the agent setup is the same idea with different package commands:
# Fedora / RHEL family
sudo dnf install -y zabbix-agent2
# Debian / Ubuntu (after adding the Zabbix repo for your release)
sudo apt install -y zabbix-agent2
Then set Server, ServerActive and Hostname, open 10050 from the server’s IP only, and enable the service. For fleets above a handful of machines, push the config with Ansible and keep a single templated zabbix_agent2.conf. Hand-editing thirty agents is how typos reach production.
Troubleshooting Common Errors
“Zabbix server is not running” in the frontend
The frontend cannot reach port 10051 on localhost. Check in this order:
sudo systemctl status zabbix-server
sudo ss -tlnp | grep 10051
sudo getsebool httpd_can_network_connect
sudo tail -50 /var/log/zabbix/zabbix_server.log
Nine times out of ten it is SELinux (httpd_can_network_connect is off) or the service crashed due to a database login problem.
“Cannot connect to the database” in the installer
Verify credentials directly:
psql -h 127.0.0.1 -U zabbix -d zabbix -c "SELECT 1;"
If that fails, the problem is pg_hba.conf or the password. If it works from the shell but not from the web, set the SELinux boolean httpd_can_network_connect_db.
Server log shows “database is down: reconnecting”
Usually a wrong DBPassword, a missing DBHost, or PostgreSQL not accepting TCP. Confirm listen_addresses = 'localhost' in postgresql.conf and that the service is up.
Agent shows red “ZBX” icon
Walk through the likely causes:
- Firewall blocks 10050 (passive checks).
Server=in the agent config doesn’t include the Zabbix server’s IP.- Wrong IP or DNS in the host’s interface.
- The agent isn’t running.
Test from the server with the bundled tool:
zabbix_get -s 10.0.20.15 -k agent.ping
If zabbix_get isn’t installed, dnf install zabbix-get provides it. A result of 1 means the connection path is fine.
Active checks never show data
Look at the agent log at /var/log/zabbix/zabbix_agent2.log. If you see “host [name] not found,” the Hostname doesn’t match the host in the frontend. Fix that, restart, and wait about two minutes.
Blank page or 500 errors in the frontend
Read the actual error instead of guessing:
sudo tail -50 /var/log/httpd/error_log
sudo tail -50 /var/log/php-fpm/www-error.log
Missing PHP modules and permissions on /etc/zabbix/web/ are the common culprits. The directory should be readable by the web server user.
dnf refuses to install: signature or repository errors
This is the Fedora 45 special. With stricter RPM verification, an unsigned package or a package whose vendor changed will be rejected. Do not bypass it with --nogpgcheck on a production host. Find out why the signature fails, whether it’s a stale metadata cache (sudo dnf clean all) or a repository that really isn’t signed.
History grows too fast and the disk fills
Check the largest tables:
psql -h 127.0.0.1 -U zabbix -d zabbix -c "SELECT relname, pg_size_pretty(pg_total_relation_size(relid)) FROM pg_catalog.pg_statio_user_tables ORDER BY pg_total_relation_size(relid) DESC LIMIT 10;"
Then shorten retention on high-volume templates, disable noisy items, or lengthen their update intervals. A 10-second interval on thousands of interface counters is the usual offender.