--- title: Run it as a service description: Keeping ClawMetry alive across reboots — launchd on macOS, systemd on Linux, supervisord, and the pattern for containers. keywords: clawmetry systemd, clawmetry launchd, run clawmetry as service, supervisord agent daemon eyebrow: Configuration --- # Run it as a service `clawmetry onboard` sets up supervision for you. This page is for when you manage processes yourself. ## What needs to run | Process | Required | Command | |---|---|---| | The sync daemon | Yes | `python -m clawmetry.sync` | | The dashboard | For the UI | `clawmetry --port 8900` | | The proxy | Optional | `clawmetry proxy start --foreground` | The daemon is the one that matters. Without it the dashboard shows nothing. ## Connecting without installing supervision ```bash clawmetry connect --key cm_xxx --no-daemon ``` That writes the configuration and leaves the process to you. ## systemd ```ini title="~/.config/systemd/user/clawmetry-sync.service" [Unit] Description=ClawMetry sync daemon After=network-online.target [Service] Type=simple ExecStart=/usr/bin/python3 -m clawmetry.sync Restart=always RestartSec=10 Environment=CLAWMETRY_HOME=%h/.clawmetry [Install] WantedBy=default.target ``` ```ini title="~/.config/systemd/user/clawmetry-dashboard.service" [Unit] Description=ClawMetry dashboard After=clawmetry-sync.service [Service] Type=simple ExecStart=/usr/local/bin/clawmetry --port 8900 --no-debug Restart=always RestartSec=10 [Install] WantedBy=default.target ``` ```bash systemctl --user daemon-reload systemctl --user enable --now clawmetry-sync clawmetry-dashboard systemctl --user status clawmetry-sync loginctl enable-linger "$USER" # survive logout ``` ## launchd (macOS) ```xml title="~/Library/LaunchAgents/com.clawmetry.sync.plist" Labelcom.clawmetry.sync ProgramArguments /usr/bin/python3 -m clawmetry.sync RunAtLoad KeepAlive WorkingDirectory/Users/YOU StandardErrorPath/tmp/clawmetry-sync.err ``` ```bash launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.clawmetry.sync.plist launchctl kickstart -k gui/$(id -u)/com.clawmetry.sync # restart after an edit ``` :::warning Set a working directory A launchd job with no `WorkingDirectory` runs with `cwd=/`, and code that resolves a relative path will fail in ways that look like a permissions problem. Set it explicitly. Also note: after editing a plist you must `bootout` and `bootstrap` again, or `kickstart -k`. Reloading alone does not pick up changes. ::: ## supervisord ```ini title="/etc/supervisor/conf.d/clawmetry.conf" [program:clawmetry-sync] command=/usr/bin/python3 -m clawmetry.sync directory=/home/agent user=agent autostart=true autorestart=true startsecs=10 stderr_logfile=/var/log/clawmetry-sync.err.log [program:clawmetry-dashboard] command=/usr/local/bin/clawmetry --port 8900 --no-debug directory=/home/agent user=agent autostart=true autorestart=true ``` ```bash supervisorctl reread && supervisorctl update supervisorctl status clawmetry-sync ``` ## Containers Run the daemon as the container's main process and the dashboard alongside it, or in a second container sharing the state volume. → [Docker](/docs/config/docker/) ## Restarting safely ```bash clawmetry sync --restart ``` This bounces the supervised service cleanly rather than sending a kill signal, so the daemon closes its DuckDB handle properly. An abrupt kill mid-write is how a store ends up needing recovery. ## Which Python A common surprise on a machine with several interpreters: the daemon runs under whichever Python the service file names, which may not be the one your shell resolves. If a version bump does not seem to take effect, check what the service is actually executing. ```bash systemctl --user show clawmetry-sync -p ExecStart ps -o command= -p "$(pgrep -f clawmetry.sync | head -1)" ``` ## Verifying ```bash clawmetry status curl -s localhost:8900/healthz ``` A monitoring check that means something: ```bash clawmetry status --json | jq -e '.daemon.running' >/dev/null ```