How To Install Zabbix on Ubuntu 26.04 LTS

Install Zabbix on Ubuntu 26.04

Monitoring is the first thing people skip on a new server and the first thing they miss when something breaks at 3 a.m. A disk fills quietly, a certificate expires over a weekend, a database replica drifts behind, and nobody knows until a customer complains. Zabbix exists to stop that sequence. It is free, mature, and scales from a single VPS to tens of thousands of monitored hosts.

Ubuntu 26.04 LTS makes a solid base for it. The release ships MariaDB 11.8.6 with full support in main, MySQL 8.4, PHP 8.5.2 and Apache 2.4.65. There is one trap. Ubuntu’s own repositories carry a Zabbix package that stays frozen for the life of the release, so the sensible route is the official Zabbix repository.

The version question matters too. Zabbix 8.0 LTS is on the roadmap for November 2026, and release candidate 2 shipped on 21 October. At the time of writing, no final day had been announced. For a production box today, Zabbix 7.0 LTS is the safe, boring, correct choice. This guide uses it, with MariaDB and Apache, then covers HTTPS, firewall rules, tuning, and the errors that actually show up in real deployments.

Which Zabbix Version Should You Install?

Short answer: 7.0 LTS. Longer answer: it depends on how much risk the machine can carry.

Zabbix publishes LTS releases with long support windows. For 8.0, the stated lifecycle is full support until Q3 2029 and limited support until Q3 2031. That is the long-term destination. But one tutorial author put it plainly: on Ubuntu 26.04, the 8.0 repository package did not yet give a stable build when they wrote it. Another guide notes that the 8.0 release package also enables an unstable source where RC packages live. That is fine for a lab. It is not what anyone wants on a billing-critical monitoring server.

Here is how the choice usually plays out:

Situation Recommended version Reason
Production monitoring, starting now 7.0 LTS Stable, long supported, well documented
Lab or proof of concept 8.0 RC Test new features and the new frontend
Existing 7.4 install Plan move to 8.0 LTS at GA 7.4 full support runs only until 8.0 LTS arrives

The latest_7.0 release package tracks the 7.0 line, so apt upgrade moves you through point releases and will not jump to 8.0 by surprise. That behavior is exactly what you want from a monitoring system.

Architecture and Sizing Before You Type Anything

Zabbix has four moving parts. The server collects and processes data. The database stores it. The web frontend (PHP) displays it. Agents run on monitored machines. Proxies sit in remote networks and forward data when needed.

For a small setup, everything lives on one machine. That is perfectly fine for up to a few hundred hosts. Beyond that, split the database off first. The database is nearly always the bottleneck, and it is the part that hurts most when it gets slow.

Rough starting points that have held up across real environments:

  • Up to 100 hosts: 2 vCPU, 4 GB RAM, 40 GB SSD.
  • 100 to 500 hosts: 4 vCPU, 8 GB RAM, NVMe or fast SSD, 100 GB or more.
  • 500+ hosts: dedicated database server, 16 GB RAM or more, and a serious look at partitioning.

Disk grows faster than people expect. History and trends data pile up, and the default retention is generous. Plan for it now rather than resizing a full volume during an outage.

Prerequisites and Preparation

A fresh Ubuntu 26.04 LTS server with sudo access is all you need. A static IP or a stable DNS name helps, because agents will point at it for years. Make sure the clock is right, since Zabbix graphs and triggers depend on correct time.

Update the system first:

sudo apt update
sudo apt full-upgrade -y
sudo reboot

If a new kernel was installed, the reboot is not optional. Running mismatched module versions is the sort of thing that bites later.

Check time sync and set a locale that will not complain:

timedatectl status
sudo timedatectl set-timezone Asia/Jakarta
sudo apt install -y wget curl ca-certificates gnupg

Swap in your own timezone. If timedatectl shows System clock synchronized: yes, you are good. If not, systemd-timesyncd or chrony will sort it out.

One cleanup worth doing: if the Zabbix packages from Ubuntu’s own repository were ever installed on this host, remove them and any leftover files before continuing. Zabbix’s own upgrade documentation warns against upgrading directly from distribution packages, because it can leave a broken installation.

dpkg -l | grep -i zabbix

On a clean server, this prints nothing. Good.

Step 1: Add the Official Zabbix Repository

Zabbix publishes one release package per Ubuntu version. Reading VERSION_ID from /etc/os-release picks the correct one, so the same lines work across releases:

. /etc/os-release
wget "https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.0+ubuntu${VERSION_ID}_all.deb"
sudo dpkg -i "zabbix-release_latest_7.0+ubuntu${VERSION_ID}_all.deb"
sudo apt update

That package only drops the repository definition and signing key on the system. It does not install any monitoring service. Confirm that apt now sees the official candidate:

apt policy zabbix-server-mysql

The candidate version should come from repo.zabbix.com, not from Ubuntu’s universe. If it shows the Ubuntu one, the repo file did not land correctly, and everything after this point will go sideways.

If a 404 appears on the download, the exact filename on the mirror may have changed. Browse https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/ and pick the file ending in ubuntu26.04_all.deb.

Step 2: Install MariaDB

Zabbix supports MariaDB and MySQL (and PostgreSQL). On 26.04, MariaDB 11.8 LTS is a first-class package, and Ubuntu now ships an AppArmor profile and a hardened systemd service for it. One important detail: MySQL and MariaDB servers are mutually exclusive on Ubuntu for now. Pick one and stay with it.

sudo apt install -y mariadb-server
sudo systemctl enable --now mariadb
sudo mariadb-secure-installation

For the secure installation prompts, set or confirm the root auth method, remove anonymous users, disallow remote root login, and drop the test database. On modern MariaDB, root uses unix socket authentication by default, which is actually safer than a password. Keep it.

Create the Zabbix database and user

sudo mariadb
CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
CREATE USER 'zabbix'@'localhost' IDENTIFIED BY 'UseALongRandomPasswordHere';
GRANT ALL PRIVILEGES ON zabbix.* TO 'zabbix'@'localhost';
SET GLOBAL log_bin_trust_function_creators = 1;
QUIT;

The utf8mb4 with utf8mb4_bin pairing is required. Zabbix compares strings case-sensitively in several places, and a case-insensitive collation causes subtle, nasty bugs. The log_bin_trust_function_creators flag is only needed during the schema import when binary logging is enabled. It gets turned back off later.

Generate a proper password instead of inventing one:

openssl rand -base64 24

Step 3: Install Zabbix Server, Frontend and Agent 2

One command pulls in the lot:

sudo apt install -y zabbix-server-mysql zabbix-frontend-php zabbix-apache-conf zabbix-sql-scripts zabbix-agent2

What each package does:

  • zabbix-server-mysql: the server daemon built for MySQL/MariaDB.
  • zabbix-frontend-php: the web interface files.
  • zabbix-apache-conf: a ready-made Apache config exposing the UI at /zabbix.
  • zabbix-sql-scripts: the initial schema and data.
  • zabbix-agent2: the modern Go-based agent, which also monitors the server itself.

Agent 2 is worth choosing over the legacy agent for new installs. It supports plugins, handles concurrent checks better, and is the one Zabbix is investing in.

Apache and the required PHP modules come in as dependencies. Check:

apache2 -v
php -v

Step 4: Import the Initial Schema

This is the step people rush, and it is where a surprising number of installs fail quietly. The import can take a minute or two on slow disks. Be patient.

zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql --default-character-set=utf8mb4 -uzabbix -p zabbix

Enter the password you set earlier. No output means success. Verify:

mysql -uzabbix -p -e "SELECT COUNT(*) FROM zabbix.users;"

You should see a small positive number. Now switch the trust flag off again:

sudo mariadb -e "SET GLOBAL log_bin_trust_function_creators = 0;"

Why bother? With binary logging on, that flag allows non-privileged users to create stored functions with potentially unsafe behavior. It was a temporary convenience. Close the door behind you.

Step 5: Configure the Zabbix Server

Open the config:

sudo nano /etc/zabbix/zabbix_server.conf

Set the database password:

DBHost=localhost
DBName=zabbix
DBUser=zabbix
DBPassword=UseALongRandomPasswordHere

Or do it non-interactively, which is handy in automation:

sudo sed -i 's/^# DBPassword=.*/DBPassword=UseALongRandomPasswordHere/' /etc/zabbix/zabbix_server.conf
grep -E '^(DBHost|DBName|DBUser|DBPassword)' /etc/zabbix/zabbix_server.conf

The config file contains a credential, so permissions matter. The packages set sensible ownership, but check:

ls -l /etc/zabbix/zabbix_server.conf

It should be readable by root and the zabbix group, not world-readable. If it is, fix it with sudo chmod 640 /etc/zabbix/zabbix_server.conf.

Step 6: Start the Services

sudo systemctl restart zabbix-server zabbix-agent2 apache2
sudo systemctl enable zabbix-server zabbix-agent2 apache2
sudo systemctl status zabbix-server --no-pager

The status should read active (running). Do not trust that alone. Read the log:

sudo tail -n 40 /var/log/zabbix/zabbix_server.log

Healthy output ends with lines like “server #0 started” for the various process types. Any line mentioning “cannot connect to database” or “access denied” means go back to Step 5.

Step 7: Finish Setup in the Web Installer

Visit http://your-server-ip/zabbix in a browser. The wizard walks through these screens:

  1. Welcome and language.
  2. Prerequisite check. Every row should be green.
  3. Database connection: type MySQL, host localhost, port 0 (default socket/port), database zabbix, the user and password you made.
  4. Settings: server name and timezone.
  5. Summary and install.

The default login is Admin with password zabbix. Change it immediately. Go to the user profile, set a long password, and ideally enable two-factor authentication under Users > Authentication. A default-credential Zabbix instance on a public IP is an invitation, and automated scanners look for exactly this.

Better still, create a personal named admin account and disable Admin or set it to a locked-down role. Named accounts make the audit log meaningful.

Securing the Frontend with HTTPS

Credentials crossing the network in cleartext is not acceptable, even on an internal network. Use TLS.

For a public DNS name, Let’s Encrypt is the practical answer:

sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d zabbix.example.com

Certbot edits the Apache vhost and sets up renewal through a systemd timer. Confirm the timer:

systemctl list-timers | grep certbot
sudo certbot renew --dry-run

For internal-only hosts without public DNS, an internal CA or a self-signed certificate works, but agents and browsers will need to trust it.

A cleaner URL helps as well. Many admins prefer serving the UI from the root of a dedicated hostname rather than /zabbix. You can do this by editing the Apache config at /etc/zabbix/apache.conf or by defining a vhost with DocumentRoot /usr/share/zabbix. Either is fine. Just be consistent, and remember that package upgrades may overwrite files in /etc/zabbix/ that you changed without care, so keep your custom vhost in /etc/apache2/sites-available/ instead.

Also add basic security headers:

sudo a2enmod headers
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000"

Only enable HSTS after confirming HTTPS works everywhere. Rolling it back is annoying.

Firewall Configuration

Zabbix uses two ports that matter: 10051/TCP for the server (receives data from active agents and proxies) and 10050/TCP for passive agent checks. The web interface uses 80 and 443.

On the Zabbix server with UFW:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 10.0.0.0/24 to any port 10051 proto tcp
sudo ufw enable
sudo ufw status verbose

Replace 10.0.0.0/24 with the real network your agents live on. Do not open 10051 to the world. Anyone who can reach that port can attempt to send data to your server.

On monitored hosts, only the Zabbix server (or proxy) IP needs to reach 10050:

sudo ufw allow from 10.0.0.5 to any port 10050 proto tcp

Order of operations matters here. Always allow SSH before enabling UFW on a remote machine. Locking yourself out of a VPS is a rite of passage, but one worth skipping.

If the host runs AlmaLinux or another RHEL-family distro elsewhere in your fleet, the equivalent is:

sudo firewall-cmd --permanent --add-port=10050/tcp
sudo firewall-cmd --reload

And on those systems, SELinux will block things in ways that look like network faults. Check getsebool -a | grep zabbix and set httpd_can_connect_zabbix or zabbix_can_network as needed.

Installing the Agent on Other Hosts

Monitoring only the Zabbix server is a sad little dashboard. Add real machines.

On another Ubuntu or Debian host, install the same release package, then the agent:

. /etc/os-release
wget "https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.0+ubuntu${VERSION_ID}_all.deb"
sudo dpkg -i "zabbix-release_latest_7.0+ubuntu${VERSION_ID}_all.deb"
sudo apt update
sudo apt install -y zabbix-agent2

Edit /etc/zabbix/zabbix_agent2.conf:

Server=10.0.0.5
ServerActive=10.0.0.5
Hostname=web01.example.com

Server lists who may poll the agent (passive checks). ServerActive is where the agent sends data on its own (active checks). Hostname must match the host name configured in the Zabbix UI exactly, character for character. A mismatch is the number one reason active checks silently never appear.

sudo systemctl enable --now zabbix-agent2
sudo systemctl status zabbix-agent2 --no-pager

For Debian, the repo path uses debian instead of ubuntu. For AlmaLinux, use the rhel path and install with dnf install zabbix-agent2. The agent config is identical.

Add the host in the frontend

Go to Data collection > Hosts > Create host. Enter the hostname, assign the template “Linux by Zabbix agent” (or the active variant), add a group, and set the agent interface to the host IP on port 10050. Within a minute or two, the availability icon should turn green.

If you manage dozens of hosts, do not click this through by hand. Use network discovery, auto-registration for active agents, or the API. Auto-registration pairs well with configuration management tools like Ansible, which can push the agent config at provisioning time.

Troubleshooting Common Errors

Here is where the time usually goes.

“Zabbix server is not running” in the frontend

The banner appears when the UI cannot reach the server process. Causes in order of likelihood: the service crashed on a bad config, the database password is wrong, or the frontend points at the wrong server host/port.

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

Fix the cause, then restart. If the service is running but the banner persists, check SELinux on RHEL-family systems, or confirm the $ZBX_SERVER and $ZBX_SERVER_PORT values in /etc/zabbix/web/zabbix.conf.php.

“Cannot connect to the database” or “Access denied”

Re-test the credentials directly:

mysql -uzabbix -p -h localhost zabbix -e "SELECT 1;"

If this fails, the user or password is wrong, or the grant is missing. If it works, the password in zabbix_server.conf or zabbix.conf.php differs from what you typed. Special characters such as # in a password can also break parsing in the config file. Use a long alphanumeric password to avoid the whole class of problem.

Schema import fails with “You do not have the SUPER privilege”

That is the binary logging setting biting. Run SET GLOBAL log_bin_trust_function_creators = 1; as root, redo the import, then switch it back to 0. If you drop and retry, drop the partially filled database first, or you will hit “table already exists”.

Agent shows red or “Cannot connect” in the host list

Work through the checklist in order:

sudo systemctl status zabbix-agent2 --no-pager
sudo ss -tlnp | grep 10050
sudo tail -n 30 /var/log/zabbix/zabbix_agent2.log

From the Zabbix server, test directly:

sudo apt install -y zabbix-get
zabbix_get -s 10.0.0.20 -p 10050 -k agent.ping

A reply of 1 means the path works. “Connection refused” suggests the agent is down or the port is wrong. A timeout points at a firewall. “Not permitted” or “no active checks” often points to a mismatch in Server= or Hostname=.

Active checks never show data

Nine times out of ten, Hostname in the agent file does not match the host name in the UI. The log will say something like “no active checks on server” or “host not found”. Match them exactly, including case, and restart the agent.

PHP errors on the prerequisites page

If the wizard complains about max_execution_time, post_max_size, or the timezone, edit the PHP values in /etc/zabbix/apache.conf, then reload Apache:

sudo systemctl reload apache2

Be aware that Ubuntu 26.04 ships a very new PHP (8.5.2). If a page throws deprecation warnings or white screens after an update, read /var/log/apache2/error.log and confirm that the installed frontend package explicitly supports the PHP version in use. The official Zabbix packages for 26.04 are built to work with it, but mixing in third-party PHP repositories like Ondrej’s PPA is a common source of trouble. Avoid mixing unless there is a clear need.

The database grows out of control

Check table sizes:

SELECT table_name, ROUND((data_length+index_length)/1024/1024) AS size_mb
FROM information_schema.tables
WHERE table_schema='zabbix'
ORDER BY (data_length+index_length) DESC LIMIT 10;

Almost always, history, history_uint and trends lead the list. Lower item history retention, remove unused templates, or raise the update interval for noisy items. Checking every item every 10 seconds when once per minute would do is a classic self-inflicted problem.

Slow frontend

Dashboards with dozens of heavy widgets hit the database hard. Reduce widget refresh rates, enable PHP OPcache (usually on by default), and verify the buffer pool is sized correctly. A slow UI usually points at a slow database rather than at Apache.

r00t is an experienced Linux enthusiast and technical writer with a passion for open-source software. With years of hands-on experience in various Linux distributions, r00t has developed a deep understanding of the Linux ecosystem and its powerful tools. He holds certifications in SCE and has contributed to several open-source projects. r00t is dedicated to sharing her knowledge and expertise through well-researched and informative articles, helping others navigate the world of Linux with confidence.

Related Posts