<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><title>IT Notes - monitoring</title><link>https://it-notes.dragas.net/categories/monitoring/</link><description>Articles in category monitoring</description><language>en</language><lastBuildDate>Thu, 07 May 2026 10:45:00 +0000</lastBuildDate><atom:link href="https://it-notes.dragas.net/categories/monitoring/feed.xml" rel="self" type="application/rss+xml"></atom:link><item><title>Monitor your devices with LibreNMS on FreeBSD</title><link>https://it-notes.dragas.net/2026/05/07/monitor-your-services-with-librenms-on-freebsd/</link><description>&lt;p&gt;&lt;img src="https://it-notes.dragas.net/featured/watchdog.webp" alt="Monitor your devices with LibreNMS on FreeBSD"&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.librenms.org"&gt;LibreNMS&lt;/a&gt; has been a faithful companion for years now. It quietly handles the monitoring of my servers, devices, and services without demanding much in return - exactly what you want from a tool whose job is to watch over everything else. It's a solid alternative to heavier solutions like Zabbix, and it gives you alerts, data, and graphs on virtually anything reachable over SNMP.&lt;/p&gt;
&lt;p&gt;I usually install it on a host that is &lt;em&gt;not&lt;/em&gt; reachable from the outside, then let it poll all the devices through a VPN: a single observation point, clean perimeter. The ability to create multiple dashboards - and to filter them by user - has also let me give clients a transparent window onto their own servers. Transparency, in my experience, is always the better long-term bet.&lt;/p&gt;
&lt;p&gt;Together with &lt;a href="https://it-notes.dragas.net/2024/07/22/install-uptime-kuma-freebsd-jail/"&gt;Uptime-Kuma&lt;/a&gt; (and the good old Nagios/Munin pair), LibreNMS lives in a FreeBSD jail on my monitoring servers and just does its job.&lt;/p&gt;
&lt;p&gt;This post walks through a plain installation of LibreNMS on FreeBSD: package-based, no reverse proxy, no HTTPS, no fancy hardening. The goal is to get to a working setup you can build on top of.&lt;/p&gt;
&lt;h2&gt;Assumptions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FreeBSD 15.0-RELEASE, in a jail or on a dedicated VM/host&lt;/li&gt;
&lt;li&gt;nginx + php-fpm + MySQL 8.4&lt;/li&gt;
&lt;li&gt;LibreNMS installed from the official package — not via &lt;code&gt;git clone&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One note before we start: in this guide I use plain HTTP just to reach the first-time setup. If your LibreNMS instance won't stay confined to a private network or behind a VPN, configuring HTTPS is mandatory, not optional.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;pkg install librenms mysql84-server python3 nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;LibreNMS currently depends on PHP 8.4. If you want to speed PHP up, install OPcache too:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;pkg install php84-opcache
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;MySQL&lt;/h2&gt;
&lt;p&gt;Two settings need to be in place &lt;em&gt;before&lt;/em&gt; MySQL starts for the first time. After the first start they cannot be changed without reinitializing the data directory, so it's worth getting them right now.&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;cd /usr/local/etc/mysql
cp my.cnf.sample my.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the &lt;code&gt;[mysqld]&lt;/code&gt; section, add:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;innodb_file_per_table=1
lower_case_table_names=0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now start MySQL:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;service mysql-server enable
service mysql-server start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;On a fresh FreeBSD install, the local &lt;code&gt;root&lt;/code&gt; user can connect to MySQL without a password from the command line. Connect and create the database and user. I'm using &lt;code&gt;password&lt;/code&gt; here as a placeholder - don't.&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;pre class="highlight"&gt;&lt;code class="language-sql"&gt;CREATE DATABASE librenms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'librenms'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON librenms.* TO 'librenms'@'localhost';
exit
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;php-fpm&lt;/h2&gt;
&lt;p&gt;Edit &lt;code&gt;/usr/local/etc/php-fpm.d/www.conf&lt;/code&gt; and adjust the listen directives:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;listen = /var/run/php-fpm-librenms.sock
listen.owner = www
listen.group = www
listen.mode = 0660
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then create &lt;code&gt;php.ini&lt;/code&gt; from the production sample:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;cd /usr/local/etc
cp php.ini-production php.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And set the timezone in &lt;code&gt;php.ini&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;date.timezone = Europe/Rome
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;nginx&lt;/h2&gt;
&lt;p&gt;Since this jail (or host) is dedicated to LibreNMS, we can rewrite the &lt;code&gt;server&lt;/code&gt; block in &lt;code&gt;/usr/local/etc/nginx/nginx.conf&lt;/code&gt; directly:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-nginx"&gt;server {
    listen      80;
    #server_name yourServerName
    root        /usr/local/www/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 /api/v0 {
        try_files $uri $uri/ /api_v0.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        set $path_info $fastcgi_path_info;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SERVER_SOFTWARE &amp;quot;&amp;quot;;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_index index.php;
        fastcgi_pass unix:/var/run/php-fpm-librenms.sock;
        fastcgi_buffers 256 4k;
        fastcgi_intercept_errors on;
        fastcgi_read_timeout 14400;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now start nginx and php-fpm:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;service nginx enable
service nginx start

service php_fpm enable
service php_fpm start
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;LibreNMS configuration&lt;/h2&gt;
&lt;p&gt;Copy the default config:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;cp /usr/local/www/librenms/config.php.default /usr/local/www/librenms/config.php
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because we installed from the package, this file already has the right commands and paths for FreeBSD - no need to hunt down &lt;code&gt;mtr&lt;/code&gt;, &lt;code&gt;fping&lt;/code&gt;, &lt;code&gt;snmpwalk&lt;/code&gt; and friends one by one.&lt;/p&gt;
&lt;p&gt;Create the directory for RRD graphs and set ownership:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;mkdir -p /var/db/librenms/rrd
chown -R www:www /var/db/librenms
chmod 775 /var/db/librenms/rrd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then the &lt;code&gt;.env&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;cd /usr/local/www/librenms
cp .env.example .env
chown www .env
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;.env&lt;/code&gt; and set at least:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DB_DATABASE&lt;/code&gt; - &lt;code&gt;librenms&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DB_USERNAME&lt;/code&gt; - &lt;code&gt;librenms&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DB_PASSWORD&lt;/code&gt; - the one you actually used (not &lt;code&gt;password&lt;/code&gt;, please)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then add this line, which tells LibreNMS we still need to run the web installer:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code&gt;INSTALL=true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A note on permissions. The official LibreNMS documentation suggests &lt;code&gt;chown -R www:www&lt;/code&gt; over the entire application tree, but on FreeBSD the package already lays down sane ownership, with &lt;code&gt;storage/&lt;/code&gt; and &lt;code&gt;bootstrap/cache/&lt;/code&gt; writable by &lt;code&gt;www&lt;/code&gt;. There's no reason to widen the rest of the codebase. If &lt;code&gt;validate.php&lt;/code&gt; complains later about something write-related, the first place to check is:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;ls -la /usr/local/www/librenms/storage /usr/local/www/librenms/bootstrap/cache
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now generate the app key as &lt;code&gt;www&lt;/code&gt;, since the file is owned by &lt;code&gt;www&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;su -m www -c &amp;quot;php artisan key:generate&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And tighten &lt;code&gt;.env&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;chmod 600 .env
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Refresh the configuration cache:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;su -m www -c &amp;quot;lnms config:clear&amp;quot;
su -m www -c &amp;quot;lnms config:cache&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Web installer&lt;/h2&gt;
&lt;p&gt;Open &lt;code&gt;http://host/install&lt;/code&gt; and follow the steps. The validation process may fail. Refreshing the cache picks up the values written to &lt;code&gt;config.php&lt;/code&gt; during the install:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;su -m www -c &amp;quot;lnms config:clear&amp;quot;
su -m www -c &amp;quot;lnms config:cache&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When the web installer is done, edit .env again and remove the INSTALL=true line if it's still there. Leaving it in place re-exposes the installer to anyone who can reach the URL.&lt;/p&gt;
&lt;h2&gt;Polling service&lt;/h2&gt;
&lt;p&gt;LibreNMS needs something to actually run the polls. On FreeBSD, the package ships an rc service that runs the LibreNMS dispatcher, so there's no need to manage cron entries by hand the way most Linux guides assume.&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;service librenms enable
service librenms start
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Validate&lt;/h2&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-sh"&gt;cd /usr/local/www/librenms
su -m www -c './validate.php'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may see a couple of complaints right after starting the service - usually scheduler-related and self-resolving within a few minutes. Re-run &lt;code&gt;validate.php&lt;/code&gt; once the dispatcher has had time to settle. Anything still red after that is worth investigating.&lt;/p&gt;
&lt;h2&gt;Next steps&lt;/h2&gt;
&lt;p&gt;At this point you can log into the web interface and start adding devices, configuring SNMP, and building dashboards. For that, the &lt;a href="https://docs.librenms.org/"&gt;official LibreNMS documentation&lt;/a&gt; is excellent, and there's no point in me paraphrasing it here.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Stefano Marinelli</dc:creator><pubDate>Thu, 07 May 2026 10:45:00 +0000</pubDate><guid isPermaLink="false">https://it-notes.dragas.net/2026/05/07/monitor-your-services-with-librenms-on-freebsd/</guid><category>freebsd</category><category>monitoring</category><category>server</category><category>networking</category><category>hosting</category><category>tutorial</category><category>security</category><category>jail</category><category>ownyourdata</category></item><item><title>Installing Uptime-Kuma in a FreeBSD Jail</title><link>https://it-notes.dragas.net/2024/07/22/install-uptime-kuma-freebsd-jail/</link><description>&lt;p&gt;&lt;img src="https://it-notes.dragas.net/featured/watchdog.webp" alt="Installing Uptime-Kuma in a FreeBSD Jail"&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/louislam/uptime-kuma"&gt;Uptime-Kuma&lt;/a&gt; is a very useful tool. Besides being able to monitor whether services, websites, or ports are responding, it can also send notifications using many different services, even combined, and check the expiration of certificates. Additionally, it can create informative dashboards about the status of services.&lt;/p&gt;
&lt;p&gt;I have been using it extensively for years, &lt;a href="https://status.bsd.cafe"&gt;including for BSD Cafe&lt;/a&gt;. My initial deployments were on Docker containers, but recently, I have &lt;a href="https://it-notes.dragas.net/2022/02/05/how-we-are-migrating-many-of-our-servers-from-linux-to-freebsd-part-1-system-and-jails-setup/"&gt;moved everything to FreeBSD jails&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;When proceeding with the standard installation described in their documentation, the process will halt because one of the third-party libraries (&lt;a href="https://playwright.dev/"&gt;Playwright&lt;/a&gt;) is not officially compatible with FreeBSD. However, since this library is not necessary for the type of checks I want to perform (I am not interested in checking web page components, just their response), it is possible to continue and run everything using a small hack.&lt;/p&gt;
&lt;p&gt;It can be installed directly on FreeBSD but, in my case, I prefer using jails. Note that if using traditional jails (i.e., not VNet), "ping" is disabled. Therefore, if using traditional jails and wanting to check hosts via ping, it is advisable to add the line &lt;code&gt;allow.raw_sockets;&lt;/code&gt; to the respective jail.conf.&lt;/p&gt;
&lt;p&gt;The installation can proceed as follows:&lt;/p&gt;
&lt;p&gt;The first step is to install the necessary dependencies:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-bash"&gt;pkg install node20 npm-node20 git-lite
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once the dependencies are installed, it is advisable to create a user to run everything and use that user for the next steps:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-bash"&gt;pw add user ukuma -m
echo 'export LC_ALL=&amp;quot;en_US.UTF-8&amp;quot;' &amp;gt;&amp;gt; /home/ukuma/.profile
su -l ukuma
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At this point, clone the Uptime-Kuma repository and start installing the dependencies:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-bash"&gt;git clone https://github.com/louislam/uptime-kuma.git
cd uptime-kuma/
npm run setup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The operation will seem to complete correctly. However, running the program will result in a fatal error preventing it from functioning:&lt;/p&gt;
&lt;pre class="highlight"&gt;&lt;code class="language-bash"&gt;ukuma@ukuma:~/uptime-kuma $ node server/server.js
[...]
/home/ukuma/uptime-kuma/node_modules/playwright-core/lib/server/registry/index.js:258
    if (process.platform === 'linux') cacheDirectory = process.env.XDG_CACHE_HOME || _path.default.join(os.homedir(), '.cache'); else if (process.platform === 'darwin') cacheDirectory = _path.default.join(os.homedir(), 'Library', 'Caches'); else if (process.platform === 'win32') cacheDirectory = process.env.LOCALAPPDATA || _path.default.join(os.homedir(), 'AppData', 'Local'); else throw new Error('Unsupported platform: ' + process.platform);
                                                                                                                                                                                                                                                                                                                                                                                             ^

Error: Unsupported platform: freebsd
    at /home/ukuma/uptime-kuma/node_modules/playwright-core/lib/server/registry/index.js:258:388
    at Object.&amp;lt;anonymous&amp;gt; (/home/ukuma/uptime-kuma/node_modules/playwright-core/lib/server/registry/index.js:270:3)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
    at Module.load (node:internal/modules/cjs/loader:1206:32)
    at Module._load (node:internal/modules/cjs/loader:1022:12)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
    at require (node:internal/modules/helpers:179:18)
    at Object.&amp;lt;anonymous&amp;gt; (/home/ukuma/uptime-kuma/node_modules/playwright-core/lib/server/index.js:84:17)
    at Module._compile (node:internal/modules/cjs/loader:1369:14)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The issue is clear: Playwright does not support FreeBSD, causing the operation to fail. At this point, there are two options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hope that Microsoft decides to support FreeBSD, which is unlikely in the short term.&lt;/li&gt;
&lt;li&gt;Trick Playwright into thinking FreeBSD is supported, which may break some related functionality, but it is a small price to pay to have all other features of Uptime-Kuma.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I will use the second method. Open the indicated file (in this case, &lt;code&gt;/home/ukuma/uptime-kuma/node_modules/playwright-core/lib/server/registry/index.js&lt;/code&gt;) and modify the indicated line (in this case, 258). Change the line &lt;code&gt;if (process.platform === 'linux')&lt;/code&gt; to &lt;code&gt;if (process.platform === 'freebsd')&lt;/code&gt; and save it.&lt;/p&gt;
&lt;p&gt;Uptime-Kuma will then be able to import the necessary libraries and function, listening on port 3001.&lt;/p&gt;
&lt;p&gt;At this point, it will be possible to use it normally, as well as use pm2 to start and manage it automatically, but this goes beyond the scope of this article.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Stefano Marinelli</dc:creator><pubDate>Mon, 22 Jul 2024 07:42:00 +0000</pubDate><guid isPermaLink="false">https://it-notes.dragas.net/2024/07/22/install-uptime-kuma-freebsd-jail/</guid><category>freebsd</category><category>monitoring</category><category>server</category><category>networking</category><category>hosting</category><category>tutorial</category><category>security</category><category>jail</category><category>container</category><category>ownyourdata</category></item></channel></rss>