Appearance
Service install
The hivecast .deb installs the same artifacts as a manual hivecast install, but additionally registers two systemd units and a journald hardening profile. This page walks through each piece.
Status: Linux-only today. The macOS
.pkgand Windows.msibuild scripts exist (projects/matrix-3/packages/hivecast/scripts/build-{macos-pkg,windows-msi}-installer.js) but are not yet a regular release artifact.
What gets installed where
Layout produced by dpkg-deb --build:
| Path | What |
|---|---|
/usr/bin/hivecast | bash wrapper that runs /opt/hivecast/node/bin/node /opt/hivecast/bin/hivecast.mjs "$@" |
/usr/bin/matrix | bash wrapper that runs /opt/hivecast/node/bin/node /opt/hivecast/bin/matrix.mjs "$@" |
/opt/hivecast/bin/hivecast.mjs | the wrapper script |
/opt/hivecast/bin/matrix.mjs | the matrix CLI shim |
/opt/hivecast/dist/host-service/cli.js | the host-service CLI |
/opt/hivecast/dist/bin/nats-server | the bundled NATS binary (mode 0755) |
/opt/hivecast/dist/node_modules/... | every bundled package, copied from the workspace build |
/opt/hivecast/node/bin/node | a vendored Node runtime (Node 20+) |
/opt/hivecast/node/lib/node_modules/npm/ | a vendored npm |
/opt/hivecast/libexec/hivecast-host-service-run | the ExecStart shim for hivecast-host.service |
/lib/systemd/system/hivecast-nats.service | NATS unit |
/lib/systemd/system/hivecast-host.service | host-service unit |
/var/lib/hivecast/ | created by postinst, owned by hivecast user (or ${SUDO_USER} if available) |
Both wrappers prepend /opt/hivecast/node/bin to PATH and set MATRIX_HOME=/var/lib/hivecast plus MATRIX_HOST_HOME=/var/lib/hivecast before exec.
The two systemd units
hivecast-nats.service
From scripts/build-deb-installer.js:107-132:
ini
[Unit]
Description=HiveCast local NATS service
After=network.target
StartLimitBurst=5
StartLimitIntervalSec=60
[Service]
Type=simple
User=hivecast
Group=hivecast
ExecStart=/opt/hivecast/dist/bin/nats-server -c /var/lib/hivecast/nats/service/nats-server.conf
Restart=on-failure
RestartSec=5s
WorkingDirectory=/var/lib/hivecast
NoNewPrivileges=true
LogRateLimitIntervalSec=10s
LogRateLimitBurst=200
MemoryHigh=512M
MemoryMax=1G
TasksMax=1024
[Install]
WantedBy=multi-user.targetThe conf file at /var/lib/hivecast/nats/service/nats-server.conf (written by postinst) sets port 4222, websocket port 4223, JetStream store_dir /var/lib/hivecast/nats/service/jetstream. Bind host is 127.0.0.1 by default, 0.0.0.0 if the postinst detects a container.
StartLimitBurst=5 + StartLimitIntervalSec=60 means after 5 failed start attempts in 60 seconds, systemd stops trying. This is the floor that RestartPreventExitStatus would target — see CLI → exit codes and diagnostics.
hivecast-host.service
From scripts/build-deb-installer.js:134-161:
ini
[Unit]
Description=HiveCast local Host service
After=hivecast-nats.service
Requires=hivecast-nats.service
StartLimitBurst=5
StartLimitIntervalSec=60
[Service]
Type=simple
User=hivecast
Group=hivecast
ExecStart=/opt/hivecast/libexec/hivecast-host-service-run
Restart=on-failure
RestartSec=5s
WorkingDirectory=/var/lib/hivecast
Environment=MATRIX_HOME=/var/lib/hivecast
Environment=MATRIX_HOST_HOME=/var/lib/hivecast
LogRateLimitIntervalSec=10s
LogRateLimitBurst=200
MemoryHigh=1G
MemoryMax=2G
TasksMax=2048
[Install]
WantedBy=multi-user.targetAfter=hivecast-nats.service + Requires=hivecast-nats.service enforce ordering: NATS must be up before host-service. Restarting hivecast-host.service does NOT restart NATS — that's the entire point of splitting them. The dev wrapper mirrors this with detached sibling NATS.
hivecast-host-service-run shim
/opt/hivecast/libexec/hivecast-host-service-run (from scripts/build-deb-installer.js:216-270) does three things:
- Spawn
host-service start --home /var/lib/hivecastand capture pid$host_pid. - Wait up to 30s (
120 * 0.25s) for/var/lib/hivecast/host.status.jsonto land. - In the background, run
hivecast bootstrap-default-runtimes(up to 6 attempts with 5s spacing). Wait on$host_pidso a Host crash terminates the whole unit.
Bootstrap output goes to /var/lib/hivecast/logs/host-bootstrap.log. The shim logs every attempt with a == header.
This shim is why the systemd unit doesn't directly ExecStart=node host-service/cli.js. The bootstrap step needs to happen after the supervisor is up, and a single command can't do both. Per CLAUDE.md's "P1.30 stop/start cycles" reference, the shim was born out of the need for clean lifecycles.
What the postinst script does
From scripts/build-deb-installer.js:272-401:
- Creates
hivecastsystem user/group if absent. - Falls back to
${SUDO_USER}for ownership if a real user invoked the install — keeps runtime files owned by the workstation user. - Detects container/cgroup environment via
/.dockerenvor/proc/1/cgroup. SetsHIVECAST_BIND_HOST=0.0.0.0for containers,127.0.0.1otherwise. - Creates
/var/lib/hivecast/andnats/service/jetstream/with mode0750. - Writes
/var/lib/hivecast/host.jsonand/var/lib/hivecast/nats/service/nats-server.confwith the bind host substituted. - Runs
hivecast seed --home /var/lib/hivecastto populate the package store. - If the working user is not
hivecast, drops drop-in unit files at/etc/systemd/system/hivecast-{nats,host}.service.d/10-workstation-user.confoverridingUser=andGroup=. - Caps journald: writes
/etc/systemd/journald.conf.d/hivecast.confwithSystemMaxUse=2G,SystemKeepFree=4G,SystemMaxFileSize=128M,MaxFileSec=1week,RuntimeMaxUse=200M,ForwardToSyslog=no,RateLimitIntervalSec=30s,RateLimitBurst=10000. Restartssystemd-journaldto pick it up. systemctl daemon-reload, thensystemctl enable && restart hivecast-{nats,host}.service.
The journald cap is launch-readiness work — without it, a runaway log emitter could fill the disk before rotation. 2 GB is the cap.
Workstation-user takeover
The drop-in pattern is the core operator-friendliness feature. If richard runs sudo dpkg -i hivecast.deb, the postinst:
- creates the
hivecastsystem user (idle) - chowns
/var/lib/hivecasttorichard:richard - writes
/etc/systemd/system/hivecast-{nats,host}.service.d/10-workstation-user.confwithUser=richard,Group=richard
So services run as richard. The hivecast system user exists but doesn't own anything live. This avoids the rabbit hole of "should the daemon run as root, or as a service user, or as me?" — the answer is: as you, by default.
The drop-in file is removed (and the hivecast user reverts to ownership) only on full purge — see Uninstall.
What prerm and postrm do
prerm (scripts/build-deb-installer.js:168-179):
systemctl stop hivecast-host.service,hivecast-nats.servicesystemctl disable hivecast-host.service,hivecast-nats.service
postrm (scripts/build-deb-installer.js:180-195) — only on purge:
- removes the workstation-user drop-in files
- removes
/etc/systemd/journald.conf.d/hivecast.conf systemctl daemon-reload
/var/lib/hivecast/ is not removed on purge — it carries credentials and state. Manual cleanup is required. See Uninstall.
See also
- Host install — the underlying
hivecast installstep that the.debpostinst runs. - Start / stop / restart — managing a service-installed Host.
- Logs —
journalctl -u hivecast-host.serviceetc. - Uninstall —
apt removevsapt purge. - Reference → Service manager integration — full unit reference.
Source:
projects/matrix-3/packages/hivecast/scripts/build-deb-installer.jslines 104-162 (units), 164-195 (maintainer scripts), 216-270 (host-service shim), 272-401 (postinst).