feat: add systemd user service for daemon mode

- contrib/teleportfling.service: per-user unit running the headless CLI
  with its own config (~/.config/teleportfling/daemon.json)
- contrib/install-daemon.sh: builds the binary, installs the unit and a
  starter daemon config
- contrib/README.md: install and management instructions
- todo.md: mark --config and daemon items complete
This commit is contained in:
2026-09-19 08:35:12 +01:00
parent 34efbaf26d
commit 973c75f3b4
4 changed files with 120 additions and 3 deletions
+40
View File
@@ -0,0 +1,40 @@
# Running TeleportFling as a daemon
`teleportfling` (the headless CLI) can run as a per-user systemd service so
the stream starts automatically with your graphical session.
## Prerequisites
- The binary must be built (the flake dev shell provides all cgo deps).
- The screen-capture backend needs the session D-Bus and a PipeWire instance,
which is why the unit is a *user* service tied to `graphical-session.target`.
## Install
```sh
./contrib/install-daemon.sh
```
This:
1. Builds `cmd/teleportfling` and installs it to `~/.local/bin/`.
2. Installs `contrib/teleportfling.service` as a user unit.
3. Creates `~/.config/teleportfling/daemon.json` on first run.
4. Runs `systemctl --user daemon-reload` and enables the service.
## Manage
```sh
systemctl --user start teleportfling # start now
systemctl --user enable teleportfling # start at login (done by installer)
systemctl --user status teleportfling # check status / logs
journalctl --user -u teleportfling -f # follow logs
systemctl --user stop teleportfling # stop
```
## Config
The unit passes `--config ~/.config/teleportfling/daemon.json`. Edit that
file to change name, port, quality, fps, source, audio or announcement, then
restart the service. Any flags you add to the `ExecStart=` line override the
file values.
+58
View File
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
# Install teleportfling as a per-user systemd service (daemon mode).
#
# Builds the headless binary, places it in ~/.local/bin, installs the user
# unit from contrib/teleportfling.service, and creates a starter daemon
# config. Run without sudo:
#
# ./contrib/install-daemon.sh
#
# Then start it with:
#
# systemctl --user enable --now teleportfling
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BIN_DIR="${HOME}/.local/bin"
SERVICE_DIR="${HOME}/.config/systemd/user"
CONFIG_DIR="${HOME}/.config/teleportfling"
CONFIG="${CONFIG_DIR}/daemon.json"
echo "Building teleportfling..."
(cd "${HERE}" && go build -o "${BIN_DIR}/teleportfling" ./cmd/teleportfling)
echo "Installing systemd user unit..."
mkdir -p "${SERVICE_DIR}"
install -m 0644 "${HERE}/contrib/teleportfling.service" "${SERVICE_DIR}/teleportfling.service"
if [[ ! -f "${CONFIG}" ]]; then
echo "Creating default daemon config at ${CONFIG}..."
mkdir -p "${CONFIG_DIR}"
cat > "${CONFIG}" <<'EOF'
{
"name": "TeleportFling Daemon",
"port": 9756,
"quality": 80,
"fps": 30,
"source": "screen",
"audio": true,
"stream_index": 0,
"announce": true
}
EOF
fi
echo "Reloading systemd and enabling the service..."
systemctl --user daemon-reload
systemctl --user enable teleportfling
cat <<EOF
Installed. Start the daemon with:
systemctl --user start teleportfling
Check status with:
systemctl --user status teleportfling
Edit settings in ${CONFIG} (the service passes it via --config).
EOF
+16
View File
@@ -0,0 +1,16 @@
[Unit]
Description=TeleportFling screen and audio stream sender
Documentation=https://github.com/fzwoch/obs-teleport
After=graphical-session.target pipewire.service
PartOf=graphical-session.target
[Service]
Type=simple
ExecStart=%h/.local/bin/teleportfling --config %h/.config/teleportfling/daemon.json
Restart=on-failure
RestartSec=2
# The capture backend needs the session bus and a PipeWire instance.
Environment=XDG_RUNTIME_DIR=%t
[Install]
WantedBy=default.target
+6 -3
View File
@@ -10,9 +10,12 @@ Backlog of deferred / planned work, tracked outside of milestone milestones.
- [ ] **Surface runtime errors in the GUI** — capture/encode failures currently
only hit the log. Show them in the status label (e.g. a denied
screen-share dialog) so problems are visible without reading logs.
- [ ] **`--config` flag** — allow the CLI and GUI to point at a custom config
path (`teleportfling --config /path/config.json`). Useful for a future
daemon or service and for running multiple profiles side by side.
- [x] **`--config` flag** — the CLI and GUI accept a custom config path
(`teleportfling --config /path/config.json`); explicit CLI flags
override file values. Used by the systemd daemon unit in contrib/.
- [x] **Run as a daemon**`contrib/install-daemon.sh` installs a per-user
systemd unit (`contrib/teleportfling.service`) that starts the headless
CLI with its own config at `~/.config/teleportfling/daemon.json`.
## Ideas (not yet scoped)