Files
unibus/deploy/README.md
T
egutierrez f6b53620e9 feat(deploy): systemd user unit + install script for membershipd
Add deploy/unibus-membershipd.service (Restart=always, binds both planes to
0.0.0.0 for LAN reachability), an idempotent deploy/install.sh that builds the
binary, symlinks the unit, and enables+starts it, plus deploy/README.md with
operate/health instructions.

Restart=always is deliberate: a clean SIGTERM exits 0 and Restart=on-failure
would not restart it, leaving the service silently dead (the sqlite_api gotcha).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 18:05:53 +02:00

68 lines
2.4 KiB
Markdown

# Running membershipd as a systemd user service
`membershipd` is the unibus control plane (rooms, members, sealed keys, blob
store) and, unless you point it at an external NATS with `--nats-url`, it also
runs the embedded NATS + JetStream data plane. Running it as a **systemd user
service** keeps it alive across logout/reboot and restarts it if it crashes.
The unit (`unibus-membershipd.service`) binds both planes to `0.0.0.0`:
| Plane | Port | Reachable from |
|--------------|-------|----------------|
| HTTP control | 8470 | LAN (`http://<host-ip>:8470/healthz`) |
| NATS data | 4250 | LAN (`nats://<host-ip>:4250`) |
## Install (idempotent)
```bash
cd ~/fn_registry/projects/message_bus/apps/unibus
./deploy/install.sh
```
This builds the binary, symlinks the unit into `~/.config/systemd/user/`,
reloads systemd, and enables + starts the service.
## Manual steps (what install.sh does)
```bash
cd ~/fn_registry/projects/message_bus/apps/unibus
# 1. Build the pure-Go binary (no CGO).
CGO_ENABLED=0 go build -o membershipd ./cmd/membershipd
# 2. Link the unit into the systemd user directory.
mkdir -p ~/.config/systemd/user
ln -sf "$PWD/deploy/unibus-membershipd.service" ~/.config/systemd/user/unibus-membershipd.service
# 3. Reload, enable (start on login) and start now.
systemctl --user daemon-reload
systemctl --user enable --now unibus-membershipd.service
# (optional) survive logout without an active session:
# sudo loginctl enable-linger "$USER"
```
## Operate
```bash
systemctl --user status unibus-membershipd.service # is it active?
systemctl --user restart unibus-membershipd.service # after a rebuild
systemctl --user stop unibus-membershipd.service
systemctl --user disable unibus-membershipd.service # stop starting on login
journalctl --user -u unibus-membershipd.service -f # follow logs
# Health (local and from another LAN host):
curl -fsS http://127.0.0.1:8470/healthz
curl -fsS http://<host-lan-ip>:8470/healthz
```
## Notes
- Writable state (SQLite DB, JetStream store, blobs) lives under `local_files/`
relative to `WorkingDirectory`, which the unit sets to the app directory.
- After editing the app code, rebuild (`CGO_ENABLED=0 go build -o membershipd
./cmd/membershipd`) and `systemctl --user restart unibus-membershipd.service`.
- To run against an external NATS instead of the embedded one, append
`--nats-url nats://<host>:4222` to `ExecStart` and re-run `daemon-reload` +
`restart`.