[Unit] Description=MeshBay Node — P2P file host, streaming, and chat Documentation=https://meshbay.org/docs After=network-online.target Wants=network-online.target # The per-user unit, for the desktop persona. # # Its sibling `meshbay-node.service` is a SYSTEM template with `User=%i`, which # root instantiates once per person (`systemctl enable --now meshbay-node@alice`) # — the ordinary gesture on a server. That is the wrong shape for someone # running a node on their own machine: it needs a password they should not have # to give, for a service that only ever runs as them. # # This one is enabled by the person themselves, and therefore by the desktop # client on their behalf: # # systemctl --user enable --now meshbay-node # loginctl enable-linger $USER # keep serving when logged out # # A user unit cannot carry User= or Group= — it already runs as its owner. [Service] Type=simple # Secrets: MESHBAY_UNLOCK_KEY (keystore). MESHBAY_PASSWORD is no longer read — # the node authenticates to the hub with an Ed25519 signature (NS7). # MESHBAY_TMDB_DEFAULT_TOKEN (Videos app, optional) also lives here — never # in source. Absent means TMDB lookups are inert until the operator sets one # here or configures a custom token in Settings (docs/MESHBAY_DESIGN.md §9.7). # MESHBAY_MUSICBRAINZ_CONTACT_DEFAULT (Music app, optional) lives here too, # same reasoning — not a credential (MusicBrainz needs none), but still # never a literal value in source: it's a personal contact address sent # as-is in every request's User-Agent (docs/MESHBAY_DESIGN.md §9.8). Absent means # MusicBrainz lookups are inert until the operator sets one here or # configures a contact in Settings. EnvironmentFile=-%h/.config/meshbay/node.env ExecStart=/opt/meshbay-common/venv/bin/meshbay-node --config %h/.config/meshbay/node.toml # The client asks for a reload after changing a group's directories, and that # must not drop a member who is watching a film. ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=10 TimeoutStopSec=30 # Data: chat DBs, roster, indexes — ~/.local/share/meshbay/ StateDirectory=meshbay # Security hardening NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=false ReadWritePaths=%h/.config/meshbay %h/.local/share/meshbay # A directory shared from outside the home — an external drive, another # partition — is added by a drop-in the client writes, rather than by weakening # ProtectSystem: # # ~/.config/systemd/user/meshbay-node.service.d/paths.conf # [Service] # ReadWritePaths=/run/media/%u/Films # RequiresMountsFor=/run/media/%u/Films # # RequiresMountsFor matters as much as the path: a unit with ProtectSystem gets # its own mount namespace, so a volume mounted on the host *after* this service # started is invisible inside it — the directory reads as empty even when # everything else is right. [Install] WantedBy=default.target