Set up Zabbix 7 monitoring server with PostgreSQL backend, SSL-enabled web interface, auto-discovery, and advanced monitoring templates for comprehensive infrastructure monitoring.
Prerequisites
- Root or sudo access
- Minimum 2GB RAM
- 10GB free disk space
- Network access for package installation
What this solves
Zabbix 7 provides enterprise-grade network and infrastructure monitoring with auto-discovery, customizable dashboards, and advanced alerting. This tutorial shows you how to install Zabbix server with PostgreSQL database backend, configure SSL-enabled web interface, set up monitoring agents with auto-discovery, and implement advanced monitoring templates for comprehensive infrastructure visibility.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions and security patches.
sudo apt update && sudo apt upgrade -y
sudo apt install -y wget curl gnupg2 software-properties-common
Install PostgreSQL database
Zabbix 7 requires PostgreSQL 13 or newer for optimal performance. We'll install PostgreSQL and create the Zabbix database.
sudo apt install -y postgresql postgresql-contrib
sudo systemctl enable --now postgresql
Configure PostgreSQL for Zabbix
Create a dedicated database and user for Zabbix with proper permissions and security settings.
sudo -u postgres createuser --pwprompt zabbix
sudo -u postgres createdb -O zabbix zabbix_db
Add Zabbix 7 repository
Add the official Zabbix repository to get the latest version 7.x packages with all features and security updates.
wget https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_7.0-2+ubuntu24.04_all.deb
sudo dpkg -i zabbix-release_7.0-2+ubuntu24.04_all.deb
sudo apt update
Install Zabbix server and web frontend
Install Zabbix server with PostgreSQL support, web frontend, and required PHP extensions.
sudo apt install -y zabbix-server-pgsql zabbix-frontend-php php8.3-pgsql zabbix-apache-conf zabbix-sql-scripts
Import Zabbix database schema
Import the initial database schema and data required for Zabbix server operation.
sudo -u zabbix psql -h localhost -d zabbix_db -f /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz
Configure Zabbix server
Configure the Zabbix server to connect to PostgreSQL database with proper security settings.
LogFile=/var/log/zabbix/zabbix_server.log
LogFileSize=10
PidFile=/run/zabbix/zabbix_server.pid
SocketDir=/run/zabbix
DBName=zabbix_db
DBUser=zabbix
DBPassword=your_zabbix_db_password
DBHost=localhost
DBPort=5432
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
Timeout=4
AlertScriptsPath=/usr/lib/zabbix/alertscripts
ExternalScripts=/usr/lib/zabbix/externalscripts
FpingLocation=/usr/bin/fping
Fping6Location=/usr/bin/fping6
LogSlowQueries=3000
StatsAllowedIP=127.0.0.1
Install and configure Apache web server
Set up Apache with SSL support for secure access to Zabbix web interface.
sudo apt install -y apache2 openssl
sudo a2enmod ssl rewrite
sudo systemctl enable --now apache2
Generate SSL certificate
Create a self-signed SSL certificate for secure HTTPS access to the Zabbix web interface.
sudo mkdir -p /etc/ssl/private /etc/ssl/certs
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/zabbix.key \
-out /etc/ssl/certs/zabbix.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=example.com"
sudo chmod 600 /etc/ssl/private/zabbix.key
sudo chmod 644 /etc/ssl/certs/zabbix.crt
Configure Apache virtual host
Set up Apache virtual host with SSL redirection and security headers for Zabbix web interface.
ServerName example.com
Redirect permanent / https://example.com/
ServerName example.com
DocumentRoot /usr/share/zabbix
SSLEngine on
SSLCertificateFile /etc/ssl/certs/zabbix.crt
SSLCertificateKeyFile /etc/ssl/private/zabbix.key
Options FollowSymLinks
AllowOverride None
Require all granted
php_value max_execution_time 300
php_value memory_limit 128M
php_value post_max_size 16M
php_value upload_max_filesize 2M
php_value max_input_time 300
php_value max_input_vars 10000
php_value always_populate_raw_post_data -1
php_value date.timezone Europe/London
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
Enable SSL site and restart Apache
Enable the SSL virtual host and restart Apache to apply the new configuration.
sudo a2ensite zabbix-ssl
sudo a2dissite 000-default
sudo systemctl restart apache2
Start Zabbix server
Enable and start the Zabbix server service to begin monitoring operations.
sudo systemctl enable --now zabbix-server
sudo systemctl status zabbix-server
Install and configure Zabbix agent
Install Zabbix agent on the server to enable self-monitoring and serve as a template for other hosts.
sudo apt install -y zabbix-agent2
Configure Zabbix agent
Configure the Zabbix agent to communicate securely with the Zabbix server and enable additional monitoring plugins.
PidFile=/run/zabbix/zabbix_agent2.pid
LogFile=/var/log/zabbix/zabbix_agent2.log
LogFileSize=10
Server=127.0.0.1
ServerActive=127.0.0.1
Hostname=zabbix-server
RefreshActiveChecks=120
BufferSend=5
BufferSize=100
MaxLinesPerSecond=20
AllowRoot=0
User=zabbix
Include=/etc/zabbix/zabbix_agent2.d/*.conf
Plugins.SystemRun.LogRemoteCommands=1
ControlSocket=/tmp/agent.sock
Start Zabbix agent
Enable and start the Zabbix agent service to begin collecting system metrics.
sudo systemctl enable --now zabbix-agent2
sudo systemctl status zabbix-agent2
Configure firewall
Open necessary ports for Zabbix server, web interface, and agent communication.
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10050/tcp
sudo ufw allow 10051/tcp
sudo ufw reload
Complete web interface setup
Access the Zabbix web interface to complete the installation wizard and configure monitoring templates.
curl -k https://localhost/zabbix/
Configure email notifications
Set up email alerts by configuring a media type for SMTP notifications in the Zabbix web interface.
Enable auto-discovery
Configure network auto-discovery to automatically detect and monitor new devices on your network.
Import advanced monitoring templates
Import additional monitoring templates for comprehensive infrastructure monitoring including databases, web servers, and network devices.
Configure maintenance windows
Set up scheduled maintenance windows to prevent false alerts during planned maintenance activities.
Optimize PostgreSQL for Zabbix
Tune PostgreSQL settings for optimal Zabbix performance with larger deployments.
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 4MB
maintenance_work_mem = 64MB
max_connections = 200
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
sudo systemctl restart postgresql
Set up automated backups
Create automated backup script for Zabbix configuration and database to ensure data protection.
#!/bin/bash
BACKUP_DIR="/backup/zabbix"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
Backup Zabbix database
pg_dump -U zabbix -h localhost zabbix_db | gzip > $BACKUP_DIR/zabbix_db_$DATE.sql.gz
Backup configuration files
tar -czf $BACKUP_DIR/zabbix_config_$DATE.tar.gz /etc/zabbix/ /usr/share/zabbix/conf/
Keep only 7 days of backups
find $BACKUP_DIR -type f -mtime +7 -delete
echo "Backup completed: $DATE" >> $BACKUP_DIR/backup.log
sudo chmod 755 /opt/zabbix-backup.sh
(crontab -l 2>/dev/null; echo "0 2 * /opt/zabbix-backup.sh") | crontab -
Verify your setup
Check that all Zabbix components are running correctly and the web interface is accessible.
sudo systemctl status zabbix-server
sudo systemctl status zabbix-agent2
sudo systemctl status apache2
sudo systemctl status postgresql
ss -tlnp | grep -E ':(80|443|10050|10051)\s'
curl -k -I https://localhost/zabbix/
sudo tail -f /var/log/zabbix/zabbix_server.log
Access the web interface and verify monitoring data collection:
# Check database connectivity
sudo -u zabbix psql -h localhost -d zabbix_db -c "SELECT COUNT(*) FROM hosts;"
Verify agent connectivity
zabbix_get -s 127.0.0.1 -k system.uptime
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Zabbix server won't start | Database connection failure | Check PostgreSQL service and credentials in /etc/zabbix/zabbix_server.conf |
| Web interface shows database error | PHP configuration or permissions | Verify PHP PostgreSQL extension: php -m | grep pgsql |
| Agent data not appearing | Firewall blocking ports | Open ports 10050/10051: sudo ufw allow 10050:10051/tcp |
| SSL certificate warnings | Self-signed certificate | Import certificate or use Let's Encrypt: sudo certbot --apache |
| Auto-discovery not working | Network permissions or SNMP | Check network connectivity and SNMP community strings |
| Email alerts not sending | SMTP configuration | Test media type configuration and check mail server logs |
| High database load | Insufficient PostgreSQL tuning | Increase shared_buffers and optimize queries in maintenance |
Next steps
- Install and configure Grafana with Prometheus for system monitoring
- Configure Zabbix SNMP monitoring for network devices
- Install and configure Loki for centralized log aggregation with Grafana integration
- Set up Zabbix high availability cluster with PostgreSQL replication
- Configure Zabbix API automation with Python scripts
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly BLUE='\033[0;34m'
readonly NC='\033[0m'
# Global variables
ZABBIX_DB_PASSWORD=""
DOMAIN_NAME=""
PKG_MGR=""
PKG_INSTALL=""
DISTRO=""
APACHE_SITES_DIR=""
APACHE_CONF_DIR=""
FIREWALL_CMD=""
# Cleanup function
cleanup() {
echo -e "${RED}[ERROR] Installation failed. Cleaning up...${NC}"
systemctl stop zabbix-server apache2 httpd postgresql 2>/dev/null || true
systemctl disable zabbix-server apache2 httpd 2>/dev/null || true
}
trap cleanup ERR
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -d DOMAIN Domain name for SSL certificate (default: $(hostname -f))"
echo " -p PASSWORD Zabbix database password (required)"
echo " -h Show this help message"
exit 1
}
log() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
exit 1
}
detect_distro() {
if [[ ! -f /etc/os-release ]]; then
error "Cannot detect distribution - /etc/os-release not found"
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
DISTRO="debian"
APACHE_SITES_DIR="/etc/apache2/sites-available"
APACHE_CONF_DIR="/etc/apache2/conf-available"
FIREWALL_CMD="ufw"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
DISTRO="rhel"
APACHE_SITES_DIR="/etc/httpd/conf.d"
APACHE_CONF_DIR="/etc/httpd/conf.d"
FIREWALL_CMD="firewall-cmd"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
DISTRO="rhel"
APACHE_SITES_DIR="/etc/httpd/conf.d"
APACHE_CONF_DIR="/etc/httpd/conf.d"
FIREWALL_CMD="firewall-cmd"
;;
*)
error "Unsupported distribution: $ID"
;;
esac
log "Detected distribution: $ID ($DISTRO-based)"
}
check_prerequisites() {
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root or with sudo"
fi
if [[ -z "$ZABBIX_DB_PASSWORD" ]]; then
error "Database password is required. Use -p option."
fi
log "Prerequisites check passed"
}
update_system() {
echo -e "${BLUE}[1/12] Updating system packages...${NC}"
if [[ "$DISTRO" == "debian" ]]; then
apt update && apt upgrade -y
$PKG_INSTALL wget curl gnupg2 software-properties-common
else
$PKG_INSTALL epel-release || true
$PKG_MGR update -y
$PKG_INSTALL wget curl gnupg2
fi
}
install_postgresql() {
echo -e "${BLUE}[2/12] Installing PostgreSQL...${NC}"
if [[ "$DISTRO" == "debian" ]]; then
$PKG_INSTALL postgresql postgresql-contrib
else
$PKG_INSTALL postgresql-server postgresql-contrib
if [[ ! -f /var/lib/pgsql/data/postgresql.conf ]]; then
postgresql-setup --initdb
fi
fi
systemctl enable --now postgresql
}
configure_postgresql() {
echo -e "${BLUE}[3/12] Configuring PostgreSQL for Zabbix...${NC}"
# Create zabbix user and database
sudo -u postgres psql -c "SELECT 1 FROM pg_user WHERE usename = 'zabbix';" | grep -q 1 || {
sudo -u postgres psql -c "CREATE USER zabbix WITH PASSWORD '$ZABBIX_DB_PASSWORD';"
}
sudo -u postgres psql -lqt | cut -d \| -f 1 | grep -qw zabbix_db || {
sudo -u postgres createdb -O zabbix zabbix_db
}
}
add_zabbix_repo() {
echo -e "${BLUE}[4/12] Adding Zabbix 7 repository...${NC}"
if [[ "$DISTRO" == "debian" ]]; then
local version_id=${VERSION_ID%%.*}
case "$ID" in
ubuntu) local repo_version="ubuntu${version_id}.04" ;;
debian) local repo_version="debian${version_id}" ;;
esac
wget -q "https://repo.zabbix.com/zabbix/7.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_7.0-2+${repo_version}_all.deb" -O /tmp/zabbix-release.deb
dpkg -i /tmp/zabbix-release.deb
apt update
else
local version_id=${VERSION_ID%%.*}
rpm -q zabbix-release || {
rpm -Uvh "https://repo.zabbix.com/zabbix/7.0/alma/${version_id}/x86_64/zabbix-release-7.0-2.el${version_id}.noarch.rpm"
}
$PKG_MGR clean all
fi
}
install_zabbix() {
echo -e "${BLUE}[5/12] Installing Zabbix server and web frontend...${NC}"
if [[ "$DISTRO" == "debian" ]]; then
$PKG_INSTALL zabbix-server-pgsql zabbix-frontend-php php-pgsql zabbix-apache-conf zabbix-sql-scripts
else
$PKG_INSTALL zabbix-server-pgsql zabbix-web-pgsql zabbix-apache-conf zabbix-sql-scripts
fi
}
import_database_schema() {
echo -e "${BLUE}[6/12] Importing Zabbix database schema...${NC}"
# Check if schema is already imported
if ! sudo -u postgres psql -d zabbix_db -c "SELECT 1 FROM users LIMIT 1;" 2>/dev/null; then
zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | sudo -u zabbix psql -h localhost -d zabbix_db
else
warn "Database schema already exists, skipping import"
fi
}
configure_zabbix_server() {
echo -e "${BLUE}[7/12] Configuring Zabbix server...${NC}"
local config_file="/etc/zabbix/zabbix_server.conf"
# Backup original config
cp "$config_file" "${config_file}.backup"
# Configure database connection
sed -i "s/^# DBPassword=/DBPassword=$ZABBIX_DB_PASSWORD/" "$config_file"
sed -i "s/^DBName=zabbix/DBName=zabbix_db/" "$config_file"
sed -i "s/^DBUser=zabbix/DBUser=zabbix/" "$config_file"
# Set other important parameters
sed -i "s/^# LogFileSize=1/LogFileSize=10/" "$config_file"
sed -i "s/^# Timeout=3/Timeout=4/" "$config_file"
sed -i "s/^# LogSlowQueries=0/LogSlowQueries=3000/" "$config_file"
}
install_apache() {
echo -e "${BLUE}[8/12] Installing Apache web server...${NC}"
if [[ "$DISTRO" == "debian" ]]; then
$PKG_INSTALL apache2 openssl
a2enmod ssl rewrite
systemctl enable --now apache2
else
$PKG_INSTALL httpd mod_ssl openssl
systemctl enable --now httpd
fi
}
generate_ssl_certificate() {
echo -e "${BLUE}[9/12] Generating SSL certificate...${NC}"
mkdir -p /etc/ssl/private /etc/ssl/certs
if [[ ! -f /etc/ssl/certs/zabbix.crt ]]; then
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/zabbix.key \
-out /etc/ssl/certs/zabbix.crt \
-subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=$DOMAIN_NAME"
chmod 640 /etc/ssl/private/zabbix.key
chmod 644 /etc/ssl/certs/zabbix.crt
if [[ "$DISTRO" == "rhel" ]]; then
chown root:apache /etc/ssl/private/zabbix.key
else
chown root:ssl-cert /etc/ssl/private/zabbix.key 2>/dev/null || chown root:root /etc/ssl/private/zabbix.key
fi
fi
}
configure_apache_ssl() {
echo -e "${BLUE}[10/12] Configuring Apache with SSL...${NC}"
local vhost_file
if [[ "$DISTRO" == "debian" ]]; then
vhost_file="$APACHE_SITES_DIR/zabbix-ssl.conf"
else
vhost_file="$APACHE_CONF_DIR/zabbix-ssl.conf"
fi
cat > "$vhost_file" << EOF
<VirtualHost *:443>
ServerName $DOMAIN_NAME
DocumentRoot /usr/share/zabbix
SSLEngine on
SSLCertificateFile /etc/ssl/certs/zabbix.crt
SSLCertificateKeyFile /etc/ssl/private/zabbix.key
<Directory "/usr/share/zabbix">
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<Directory "/usr/share/zabbix/conf">
Require all denied
</Directory>
<Directory "/usr/share/zabbix/app">
Require all denied
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName $DOMAIN_NAME
Redirect permanent / https://$DOMAIN_NAME/
</VirtualHost>
EOF
if [[ "$DISTRO" == "debian" ]]; then
a2ensite zabbix-ssl.conf
fi
systemctl restart apache2 httpd 2>/dev/null || true
}
configure_firewall() {
echo -e "${BLUE}[11/12] Configuring firewall...${NC}"
if [[ "$FIREWALL_CMD" == "ufw" ]]; then
ufw --force enable 2>/dev/null || true
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow 10051/tcp
elif [[ "$FIREWALL_CMD" == "firewall-cmd" ]]; then
systemctl enable --now firewalld 2>/dev/null || true
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=10051/tcp
firewall-cmd --reload
fi
}
start_services() {
echo -e "${BLUE}[12/12] Starting services...${NC}"
systemctl enable --now zabbix-server
if [[ "$DISTRO" == "debian" ]]; then
systemctl restart apache2
else
systemctl restart httpd
fi
# Wait for services to start
sleep 5
# Verify services are running
systemctl is-active --quiet postgresql || error "PostgreSQL failed to start"
systemctl is-active --quiet zabbix-server || error "Zabbix server failed to start"
if [[ "$DISTRO" == "debian" ]]; then
systemctl is-active --quiet apache2 || error "Apache failed to start"
else
systemctl is-active --quiet httpd || error "Apache failed to start"
fi
}
main() {
# Parse command line arguments
while getopts "d:p:h" opt; do
case $opt in
d) DOMAIN_NAME="$OPTARG" ;;
p) ZABBIX_DB_PASSWORD="$OPTARG" ;;
h) usage ;;
*) usage ;;
esac
done
# Set default domain if not provided
[[ -z "$DOMAIN_NAME" ]] && DOMAIN_NAME=$(hostname -f 2>/dev/null || hostname)
detect_distro
check_prerequisites
log "Starting Zabbix 7 installation with PostgreSQL"
log "Domain: $DOMAIN_NAME"
update_system
install_postgresql
configure_postgresql
add_zabbix_repo
install_zabbix
import_database_schema
configure_zabbix_server
install_apache
generate_ssl_certificate
configure_apache_ssl
configure_firewall
start_services
log "Installation completed successfully!"
log "Access Zabbix at: https://$DOMAIN_NAME"
log "Default credentials: Admin / zabbix"
log "Database password: $ZABBIX_DB_PASSWORD"
warn "Please change the default admin password after first login"
}
main "$@"
Review the script before running. Execute with: bash install.sh