Seeking advice to contribute an uptime-kuma port

Hi everyone,

I'm seeking advice on creating an uptime-kuma port, hopefully for the eventual submission to the official ports tree, given its NodeJS nature and the fact that its installation process basically consists of the downloading of a collection of npm dependencies. If I'm not mistaken, this could present the official ports tree and/or poudriere builders with problems.

Additionally, uptime-kuma claims it doesn't support FreeBSD, but I did manage to get it working without much fuss, both its older 1.x and its current 2.0 releases, inside of a 13.5 jail via the rc script below.

Thank you in advance for any tips on how to approach this, most appreciated! And, needless to say, please feel free to critique my rc script.

sh:
#!/bin/sh

# uptime-kuma FreeBSD Service Script

# PROVIDE: uptime_kuma
# REQUIRE: NETWORKING
# KEYWORD: shutdown
#
# Optional settings:
# uptime_kuma_user (system user): User who will run the service.
# uptime_kuma_group (system group): Service user's main group.
# uptime_kuma_home (path): Uptime Kuma installation directory.
# uptime_kuma_data_path (path): Uptime Kuma data directory.
# uptime_kuma_browsers_path (path): Microsoft Playwright's browsers path (https://playwright.dev/docs/browsers#managing-browser-binaries).
# uptime_kuma_host (IP address): Service host.
# uptime_kuma_port (TCP port): Service port.

. /etc/rc.subr

name=uptime_kuma
rcvar=${name}_enable

load_rc_config $name

: ${uptime_kuma_enable:=NO}
: ${uptime_kuma_user:=www}
: ${uptime_kuma_group:=www}
: ${uptime_kuma_home:=/usr/local/www/uptime-kuma}
: ${uptime_kuma_data_path:=${uptime_kuma_home}/data}
: ${uptime_kuma_browsers_path:=/nonexistent}
: ${uptime_kuma_host:=0.0.0.0}
: ${uptime_kuma_port:=3001}

eval ${name}_chdir=${uptime_kuma_home}
eval ${name}_env="\"HOME=${uptime_kuma_home} PLAYWRIGHT_BROWSERS_PATH=${uptime_kuma_browsers_path}\""

dashname=$(echo ${name} | tr _ -)
pidfile=/var/run/${dashname}/${dashname}.pid
command=/usr/sbin/daemon
command_args="-r -f -o /var/log/${dashname}/${dashname}.log -H -P ${pidfile} /usr/local/bin/node ${uptime_kuma_home}/server/server.js -- --name ${dashname} --host=${uptime_kuma_host} --port=${uptime_kuma_port}"
start_precmd=start_precmd

start_precmd()
{
    [ -d /var/log/${dashname} ] || install -d -o ${uptime_kuma_user} -g ${uptime_kuma_group} /var/log/${dashname}
    [ -d /var/run/${dashname} ] || install -d -o ${uptime_kuma_user} -g ${uptime_kuma_group} /var/run/${dashname}
}

run_rc_command "$1"
 
Some small corrections and refinements to Uptime Kuma's rc script:

sh:
#!/bin/sh

# PROVIDE: uptime_kuma
# REQUIRE: NETWORKING DAEMON
# KEYWORD: shutdown
#
# Optional settings:
# uptime_kuma_user (system user): User who will run the service.
# uptime_kuma_group (system group): Service user's main group.
# uptime_kuma_deployment_path (path): Uptime Kuma installation directory.
# uptime_kuma_data_path (path): Uptime Kuma data directory.
# uptime_kuma_browsers_path (path): Microsoft Playwright's browsers path (https://playwright.dev/docs/browsers#managing-browser-binaries).
# uptime_kuma_host (IP address): Service host.
# uptime_kuma_port (TCP port): Service port.

. /etc/rc.subr

name="uptime_kuma"
rcvar="${name}_enable"

load_rc_config $name

: ${uptime_kuma_enable:="NO"}
: ${uptime_kuma_user:="www"}
: ${uptime_kuma_group:="www"}
: ${uptime_kuma_deployment_path:="/usr/local/www/$(echo ${name} | tr _ -)"}
: ${uptime_kuma_data_path:="${uptime_kuma_deployment_path}/data"}
: ${uptime_kuma_browsers_path:="/nonexistent"}
: ${uptime_kuma_host:="0.0.0.0"}
: ${uptime_kuma_port:="3001"}

pidfile="/var/run/${name}/${name}.pid"
command="/usr/sbin/daemon"
uptime_kuma_flags="-t ${name} -P ${pidfile} -r -f -o /var/log/${name}/${name}.log -H"
command_args="/usr/local/bin/node ${uptime_kuma_deployment_path}/server/server.js -- --host=${uptime_kuma_host} --port=${uptime_kuma_port}"

eval uptime_kuma_chdir="${uptime_kuma_deployment_path}"
eval uptime_kuma_env="\"HOME=${uptime_kuma_deployment_path} PLAYWRIGHT_BROWSERS_PATH=${uptime_kuma_browsers_path}\""

start_precmd="${name}_start_precmd"

uptime_kuma_start_precmd()
{
    [ -d "/var/log/${name}" ] || install -d -o "${uptime_kuma_user}" -g "${uptime_kuma_group}" "/var/log/${name}"
    [ -d "/var/run/${name}" ] || install -d -o "${uptime_kuma_user}" -g "${uptime_kuma_group}" "/var/run/${name}"
}

run_rc_command "$1"
 
Some small corrections and refinements to Uptime Kuma's rc script:

sh:
#!/bin/sh

# PROVIDE: uptime_kuma
# REQUIRE: NETWORKING DAEMON
# KEYWORD: shutdown
#
# Optional settings:
# uptime_kuma_user (system user): User who will run the service.
# uptime_kuma_group (system group): Service user's main group.
# uptime_kuma_deployment_path (path): Uptime Kuma installation directory.
# uptime_kuma_data_path (path): Uptime Kuma data directory.
# uptime_kuma_browsers_path (path): Microsoft Playwright's browsers path (https://playwright.dev/docs/browsers#managing-browser-binaries).
# uptime_kuma_host (IP address): Service host.
# uptime_kuma_port (TCP port): Service port.

. /etc/rc.subr

name="uptime_kuma"
rcvar="${name}_enable"

load_rc_config $name

: ${uptime_kuma_enable:="NO"}
: ${uptime_kuma_user:="www"}
: ${uptime_kuma_group:="www"}
: ${uptime_kuma_deployment_path:="/usr/local/www/$(echo ${name} | tr _ -)"}
: ${uptime_kuma_data_path:="${uptime_kuma_deployment_path}/data"}
: ${uptime_kuma_browsers_path:="/nonexistent"}
: ${uptime_kuma_host:="0.0.0.0"}
: ${uptime_kuma_port:="3001"}

pidfile="/var/run/${name}/${name}.pid"
command="/usr/sbin/daemon"
uptime_kuma_flags="-t ${name} -P ${pidfile} -r -f -o /var/log/${name}/${name}.log -H"
command_args="/usr/local/bin/node ${uptime_kuma_deployment_path}/server/server.js -- --host=${uptime_kuma_host} --port=${uptime_kuma_port}"

eval uptime_kuma_chdir="${uptime_kuma_deployment_path}"
eval uptime_kuma_env="\"HOME=${uptime_kuma_deployment_path} PLAYWRIGHT_BROWSERS_PATH=${uptime_kuma_browsers_path}\""

start_precmd="${name}_start_precmd"

uptime_kuma_start_precmd()
{
    [ -d "/var/log/${name}" ] || install -d -o "${uptime_kuma_user}" -g "${uptime_kuma_group}" "/var/log/${name}"
    [ -d "/var/run/${name}" ] || install -d -o "${uptime_kuma_user}" -g "${uptime_kuma_group}" "/var/run/${name}"
}

run_rc_command "$1"
Happy to help port this.
 
I can also confirm that Uptime Kuma worths perfectly in FreeBSD, but I’m too lazy to work on a port, so I just use an install script.


My rc script is slightly different than yours, but everything works, including the 2.x versions.
Maybe you can make the repo public? It 404s here. Having a working script to start will be helpful.
 
Maybe you can make the repo public? It 404s here. Having a working script to start will be helpful.
I just clicked it and it’s working. It is public.

I did have to edit the post a couple minutes after I posted to correct the link, but it’s been working since then.
 
Happy to help port this.
Lovely!

I've been using Uptime Kuma for a long while already on FreeBSD, both through iocage and now through BastilleBSD, and it's become an integral part of my infrastructure.

Below is my most recent version of the rc(8) script, simplified from previous versions I've posted here to remove unnecessary abstractions on things that will hardly change, and to better adhere to rc(8) best practices. Please feel free to critique as appropriate!

sh:
#!/bin/sh

# PROVIDE: uptime_kuma
# REQUIRE: NETWORKING DAEMON
# KEYWORD: shutdown
#
# Mandatory settings:
# uptime_kuma_enable: Service enable knob.
#
# Optional settings:
# uptime_kuma_host (IP address): Service host.
# uptime_kuma_port (TCP port): Service port.


. /etc/rc.subr

name="uptime_kuma"
rcvar="${name}_enable"

load_rc_config $name

: ${uptime_kuma_enable:="NO"}
: ${uptime_kuma_host:="0.0.0.0"}
: ${uptime_kuma_port:="3001"}

pidfile="/var/run/${name}/${name}.pid"
command="/usr/sbin/daemon"
uptime_kuma_flags="-t ${name} -P ${pidfile} -r -f -o /var/log/${name}/${name}.log -H"
uptime_kuma_deployment_path="/usr/local/www/$(echo ${name} | tr _ -)"
command_args="/usr/local/bin/node ${uptime_kuma_deployment_path}/server/server.js -- --host=${uptime_kuma_host} --port=${uptime_kuma_port}"
uptime_kuma_user="www"
uptime_kuma_group="www"

eval uptime_kuma_chdir="${uptime_kuma_deployment_path}"
# Microsoft Playwright's browsers path (https://playwright.dev/docs/browsers#managing-browser-binaries).
eval uptime_kuma_env="\"HOME=${uptime_kuma_deployment_path} PLAYWRIGHT_BROWSERS_PATH=/nonexistent\""

start_precmd="uptime_kuma_start_precmd"

uptime_kuma_start_precmd()
{
    [ -d "/var/log/${name}" ] || install -d -o "${uptime_kuma_user}" -g "${uptime_kuma_group}" "/var/log/${name}"
    [ -d "/var/run/${name}" ] || install -d -o "${uptime_kuma_user}" -g "${uptime_kuma_group}" "/var/run/${name}"
}

run_rc_command "$1"

If anyone's interested in how I deploy this service via Bastille, I'd be open to discussing sharing of that code.
 
I can also confirm that Uptime Kuma worths perfectly in FreeBSD, but I’m too lazy to work on a port, so I just use an install script.


My rc script is slightly different than yours, but everything works, including the 2.x versions.
Just upgraded to 2.3.2 a few minutes ago on a 14.4-RELEASE-p5 Bastille jail, all working like a charm!
 
here's a port. I've been using this on 2.3.2 without issues, and just updated to 2.4.0 today & committed. In the usual nodejs way, it comprises ~ 13_000 files, after substantial pruning, but around 80MiB compressed as a package tarball.

- review: https://reviews.freebsd.org/D57369
- git branch: https://git.sr.ht/~dch/ports/log/uptime-kuma

Some of Uptime Kuma's many npm dependencies are simply not being updated and for a tool that often has login credentials to monitored sites, and is by design directly exposed to the internet, is not responsible.

Code:
(cd /tmp//usr/ports/net-mgmt/uptime-kuma/work/uptime-kuma-2.4.0 &&  /usr/bin/env HOME=/tmp//usr/ports/net-mgmt/uptime-kuma/work npm_config_cache=/tmp//usr/ports/net-mgmt/uptime-kuma/work/.npm  npm ci --legacy-peer-deps --no-audit --no-fund)
npm warn deprecated whatwg-encoding@3.1.1: Use @exodus/bytes instead for a more spec-conformant and faster implementation
npm warn deprecated tar@6.2.1: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated source-map-resolve@0.6.0: See https://github.com/lydell/source-map-resolve#deprecated
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm warn deprecated npmlog@5.0.1: This package is no longer supported.
npm warn deprecated lodash.get@4.4.2: This package is deprecated. Use the optional chaining (?.) operator instead.
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated glob@7.2.3: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated gauge@3.0.2: This package is no longer supported.
npm warn deprecated event-to-promise@0.7.0: Use promise-toolbox/fromEvent instead
npm warn deprecated eslint@8.14.0: This version is no longer supported. Please see https://eslint.org/version-support for other options.
npm warn deprecated are-we-there-yet@2.0.0: This package is no longer supported.
npm warn deprecated @npmcli/move-file@1.1.2: This functionality has been moved to @npmcli/fs
npm warn deprecated @humanwhocodes/config-array@0.9.5: Use @eslint/config-array instead
npm warn deprecated @humanwhocodes/object-schema@1.2.1: Use @eslint/object-schema instead
npm warn deprecated @playwright/test@1.39.0: Please update to the latest version of Playwright to test up-to-date browsers.
npm warn deprecated @hey-api/client-fetch@0.10.2: Starting with v0.73.0, this package is bundled directly inside @hey-api/openapi-ts.
npm warn deprecated glob@10.3.16: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated are-we-there-yet@3.0.1: This package is no longer supported.
npm warn deprecated gauge@4.0.4: This package is no longer supported.
npm warn deprecated npmlog@6.0.2: This package is no longer supported.
npm warn deprecated uuid@8.3.2: uuid@10 and below is no longer supported.  For ESM codebases, update to uuid@latest.  For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
npm warn deprecated uuid@10.0.0: uuid@10 and below is no longer supported.  For ESM codebases, update to uuid@latest.  For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).
npm warn deprecated glob@10.5.0: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated core-js@2.6.12: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
added 1266 packages in 35s

If you encounter any issues, please drop a note in bugzilla.
 
Awesome, thank you for putting this together! Also, I see you added a patch to relocate the error log, which I'd been wanting to do, so this is most appreciated.

Hope this gets accepted into the tree! Let me know if you'd like me to help with any testing to move it along the process.
 
Back
Top