Target: LibreNMS on Nginx + PHP-FPM + MariaDB + RRDtool, with SNMP
polling and the lnms fping/dispatcher cron pipeline. Sized for
monitoring a small-to-mid fleet (dozens to low hundreds of hosts) on a
2 vCPU / 4GB RamNode KVM instance.
0. Assumptions
- Fresh Ubuntu 24.04 LTS VPS, non-root sudo user
- You have (or will create) an SNMP community string / v3 creds for the devices you're polling (hypervisor nodes, switches, etc.)
1. Base packages
sudo apt update && sudo apt upgrade -y
sudo apt install -y software-properties-common curl composer git \
fping graphviz imagemagick mtr-tiny nmap python3-pip \
python3-dotenv python3-pymysql python3-redis python3-setuptools \
python3-systemd python3-pip snmp snmpd rrdtool whois unzip2. Create the librenms system user
sudo useradd librenms -d /opt/librenms -M -r -s "$(command -v bash)"3. Fetch LibreNMS
cd /opt
sudo git clone https://github.com/librenms/librenms.git
sudo chown -R librenms:librenms /opt/librenms
sudo chmod 771 /opt/librenms
sudo setfacl -d -m g::rwx /opt/librenms/rrd /opt/librenms/logs \
/opt/librenms/bootstrap/cache/ /opt/librenms/storage/
sudo setfacl -R -m g::rwx /opt/librenms/rrd /opt/librenms/logs \
/opt/librenms/bootstrap/cache/ /opt/librenms/storage/4. PHP 8.2+ and required extensions
Ubuntu 24.04's default repo PHP (8.3) works fine — no need for Ondrej's PPA unless you want a newer minor version.
sudo apt install -y php php-fpm php-cli php-mysql php-gd php-json \
php-curl php-snmp php-xml php-mbstring php-zip php-bcmath php-gmpSet timezone in PHP config (must match system):
TZ=$(cat /etc/timezone)
sudo sed -i "s/;date.timezone =/date.timezone = ${TZ//\//\\/}/" /etc/php/8.3/fpm/php.ini
sudo sed -i "s/;date.timezone =/date.timezone = ${TZ//\//\\/}/" /etc/php/8.3/cli/php.ini5. MariaDB
sudo apt install -y mariadb-server mariadb-client
sudo systemctl enable --now mariadb
sudo mysql_secure_installationTune /etc/mysql/mariadb.conf.d/50-server.cnf — add under [mysqld]:
innodb_file_per_table=1
lower_case_table_names=0Restart and create the DB:
sudo systemctl restart mariadb
sudo mysql -u root -p <<'EOF'
CREATE DATABASE librenms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'librenms'@'localhost' IDENTIFIED BY 'CHANGE_ME_STRONG_PW';
GRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'localhost';
FLUSH PRIVILEGES;
EOF6. PHP-FPM pool
sudo cp /etc/php/8.3/fpm/pool.d/www.conf /etc/php/8.3/fpm/pool.d/librenms.conf
sudo sed -i 's/\[www\]/[librenms]/' /etc/php/8.3/fpm/pool.d/librenms.conf
sudo sed -i 's/user = www-data/user = librenms/' /etc/php/8.3/fpm/pool.d/librenms.conf
sudo sed -i 's/group = www-data/group = librenms/' /etc/php/8.3/fpm/pool.d/librenms.conf
sudo sed -i 's|listen = .*|listen = /run/php-fpm-librenms.sock|' /etc/php/8.3/fpm/pool.d/librenms.conf
sudo systemctl restart php8.3-fpm7. Nginx vhost
sudo apt install -y nginx
sudo rm -f /etc/nginx/sites-enabled/default/etc/nginx/sites-available/librenms:
server {
listen 80;
server_name librenms.example.com;
root /opt/librenms/html;
index index.php;
charset utf-8;
gzip on;
gzip_types text/css application/javascript text/javascript application/x-javascript image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ [^/]\.php(/|$) {
fastcgi_pass unix:/run/php-fpm-librenms.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi.conf;
}
location /api/v0 {
try_files $uri $uri/ /api_v0.php?$query_string;
}
}sudo ln -s /etc/nginx/sites-available/librenms /etc/nginx/sites-enabled/librenms
sudo nginx -t && sudo systemctl reload nginxLayer TLS with certbot the same way as any other vhost:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d librenms.example.com8. lnms CLI and dependencies
cd /opt/librenms
sudo -u librenms composer install --no-devSymlink the CLI helper:
sudo ln -s /opt/librenms/lnms /usr/bin/lnms
sudo cp /opt/librenms/misc/lnms-completion.bash /etc/bash_completion.d/9. Web installer
Browse to http://librenms.example.com/install (or https:// once TLS
is up) and walk through the guided DB setup — it writes
/opt/librenms/.env for you. Alternatively do it headless:
cd /opt/librenms
sudo -u librenms cp .env.example .env
sudo -u librenms php artisan key:generateThen edit .env:
APP_URL=https://librenms.example.com
DB_HOST=localhost
DB_DATABASE=librenms
DB_USERNAME=librenms
DB_PASSWORD=CHANGE_ME_STRONG_PWRun migrations and create the first admin user:
sudo -u librenms php artisan migrate --force
sudo -u librenms /opt/librenms/lnms user:add -r admin -e you@example.com admin10. SNMPd (only needed if this VPS itself is a polled device)
sudo cp /opt/librenms/misc/snmpd.conf.example /etc/snmp/snmpd.conf
sudo sed -i 's/RANDOMSTRINGGOESHERE/YOUR_RO_COMMUNITY/' /etc/snmp/snmpd.conf
sudo systemctl enable --now snmpdFor polling other devices (the actual point of LibreNMS), no local
snmpd config is needed — creds are stored per-device in the web UI or
via lnms device:add.
11. Cron / scheduler
sudo cp /opt/librenms/librenms.nonroot.cron /etc/cron.d/librenmsThis drives discovery, polling, alerting, and billing every minute via the dispatcher service. For higher-scale polling, switch to the distributed poller service instead of cron-based polling:
sudo cp /opt/librenms/librenms.service /etc/systemd/system/
sudo systemctl enable --now librenmsLogrotate:
sudo cp /opt/librenms/misc/librenms.logrotate /etc/logrotate.d/librenms12. Add your first device
sudo -u librenms lnms device:add nlxsvz71.ramnode.com -v v2c -c YOUR_RO_COMMUNITY
sudo -u librenms lnms discovery:run -h all
sudo -u librenms lnms poller:run -h all13. Validate
sudo -u librenms php /opt/librenms/validate.phpThis checks permissions, PHP extensions, cron health, and DB schema version — fix anything it flags before relying on the install.
14. Firewall
sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw enablePolling traffic (SNMP/ICMP outbound to monitored hosts) doesn't need
inbound rules unless devices are configured to send traps back — if so,
also open 162/udp.
