Потребовалось довольно срочно реализовать сервис мониторинга и выбор пал на Uptime Kuma. Процесс установки сервиса хорошо описан тут. Ниже будет описан «не докерный» вариант установки версии 1.23.16 с особенностями для Devuan GNU+Linux.
Готовимся
Здесь и далее я всё делал из-под root, использовал для reverce-proxy веб-сервер apache2 и в принципе игнорировал нормальные практики. На старте было что-то такое:
12.11
root@host:~$ cat /etc/devuan_version
daedalus
root@host:~$ uname -a
Linux host 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64 GNU/Linux
Обновляем систему:
Устанавливаем веб-сервер:
Устанавливаем всякое что может пригодиться:
Устанавливаем NodeJS:
Устанавливаем NPM:
Просто на всякий случай… устанавливаем git:
Переходим к сервису
Клонируем git репозиторий в /opt/uptime-kuma:
root@host:~$ git clone https://github.com/louislam/uptime-kuma.git
Устанавливаем pm2 production manager:
root@host:~$ npm install pm2 -g
Собственно устанавливаем:
После установки, приложение/сервер можно запустить:
root@host:~$ pm2 start server/server.js --name uptime-kuma
NB! При использовании сервиса я столкнулся с тем, что сайты и приложения которые нужно мониторить, не всегда отдают корректные заголовки, что приводит к ошибке «Parse Error: Invalid header value char». Проблема отчасти описана и решена тут.
Решение выглядит так:
root@host:~$ pm2 start server/server.js --name uptime-kuma --node-args="--insecure-http-parser"
Далее, для того чтобы сервис запустился автоматически хоть с какой-то долей вероятности, необходимо сделать следующее:
root@host:~$ pm2 startup systemv
root@host:~$ pm2 startup save
root@host:~$ update-rc.d pm2-root defaults
Вторая команда завершится с ошибкой, но это нормально. Такие сложности вызваны тем, что sysvinit в pm2 поддерживается только для CENTOS6 и скрипты завязаны на утилиты, которых в Debian и соответственно Devuan нет, так что, спасибо и на том что инит-скрипт нормально создаётся, а автостарт можно и руками. Напоминаю, что root в pm2-root это имя пользователя, и если у Вас там что-то отличное от root (например, имя пользователя от которого запущен su), то надо либо всё переделать сначала, либо как минимум поправить пользователя от которого идет работа скрипта /etc/init.d/pm2-username. Вместо update-rc.d pm2-root defaults можно использовать утилиту rcconf.
Реверс-прокси
Для того чтобы всё это начало не только работать, но и радовать глаз в браузере, необходимо настроить реверс-прокси. Как это сделать описано тут, но в целом порядок следующий.
Создаём vhost:
root@host:~$ mcedit ./uptime-kuma.conf
С содержимым:
ServerName YOUR_DOMAIN_NAME_HERE.org
ProxyPreserveHost on
ProxyPass / http://localhost:3001/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://localhost:3001/$1" [P,L]
</VirtualHost>
Даём команды:
root@host:~$ a2enmod proxy
root@host:~$ a2enmod proxy_http
root@host:~$ a2enmod ssl
root@host:~$ a2enmod rewrite
root@host:~$ a2enmod headers
root@host:~$ service apache2 restart
и на этом моменте получаем доступный по http интерфейс администратора uptime-kuma на http://YOUR_DOMAIN_NAME_HERE.org:80.
Сертификат
Далее, выпускаем сертификат для сервиса:
И убеждаемся что получившийся вхост содержит всё что нужно:
root@host:~$ mcedit ./uptime-kuma-le-ssl.conf
В моём случае содержимое выглядит так:
<VirtualHost *:443>
ServerName MY_PRIVATE_3RD_LEVEL_DOMAIN_NAME.ideafix.su
DocumentRoot /var/www/html/
Protocols h2 http/1.1
ProxyPreserveHost on
ProxyPass / http://localhost:3001/
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /(.*) ws://localhost:3001/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /(.*) http://localhost:3001/$1 [P,L]
#RewriteCond %{HTTP:Upgrade} websocket [NC]
#RewriteCond %{HTTP:Connection} upgrade [NC]
#RewriteRule ^/?(.*) "ws://localhost:3001/$1" [P,L]
RequestHeader set X-Forwarded-Proto "http"
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLCertificateFile /etc/letsencrypt/live/MY_PRIVATE_3RD_LEVEL_DOMAIN_NAME.ideafix.su/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/MY_PRIVATE_3RD_LEVEL_DOMAIN_NAME.ideafix.su/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
За «MY_PRIVATE_3RD_LEVEL_DOMAIN_NAME» прошу простить, не удержался. Из отличий от официального мануала можно отметить строки:
RequestHeader set X-Forwarded-Proto "http"
Первая позволит куда-то положить к примеру .htaccess, вторая — передаст реальный адрес клиента.
После выпуска сертификата и создания нового вхоста, нужно перезапустить веб-сервер:
root@host:~$ service apache2 restart
Проблемки
Так же в процессе создания мониторов я столкнулся с ошибкой ‘unable to verify the first certificate‘. Проблема довольно хорошо описана тут. В моём случае скорее всего проблема была вызвана не верной концигурацией веб-сервера, который нужно было мониторить. То есть я допускаю что проблема действительно была, но ни один из дюжины десктопных или мобильных браузеров, а так же пара антивирусов ни-че-го не сказали про плохой сертификат, не защищенное подключение и пр. Более того, онлайн сервис, который указал бы на проблему с промежуточным сертификатом тоже пришлось искать. В общем, это опять не проблема uptime-kuma, а проблема NodeJS. Я использовал решение, описанное здесь — т.е. просто создал по инструкции intermediate.pem, добавил строку в конфиг pm2:
"NODE_EXTRA_CA_CERTS": "/root/intermediate.pem",
и перезапустил весь pm2 (не uptime-kuma, весь pm2):
На самом деле это не то, чтобы очень удобно. Разработчик приложения говорит «конфигурируйте вашу ноду», а если у меня сотни мониторов и половина с чудесами? Получается, что решать продобные проблемы пользователь будет самостоятельно. Прошу обратить внимание, команда cat /root/.pm2/dump.pm2 | grep pem не редактирует файл /root/.pm2/dump.pm2.
Итого
В сухом остатке хотелось бы отметить что pm2 стал второй для меня серьезной проблемой в Devuan GNU+Linux. Проблема, это когда программное обеспечение присутствует в дистрибутиве/репозитории, но из-за отсутствия systemd не может работать нормально. Первой же проблемой стал Apache Tomcat, который теперь многие runtime-настрйоки получает через параметры unit-файла, а альтернативные варианты либо не документированы, либо сломаны, либо очень уж не изящны.