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#
clawmetry connect --key cm_xxx --no-daemonThat writes the configuration and leaves the process to you.
systemd#
[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[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.targetsystemctl --user daemon-reload
systemctl --user enable --now clawmetry-sync clawmetry-dashboard
systemctl --user status clawmetry-sync
loginctl enable-linger "$USER" # survive logoutlaunchd (macOS)#
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.clawmetry.sync</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>-m</string>
<string>clawmetry.sync</string>
</array>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>WorkingDirectory</key><string>/Users/YOU</string>
<key>StandardErrorPath</key><string>/tmp/clawmetry-sync.err</string>
</dict>
</plist>launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.clawmetry.sync.plist
launchctl kickstart -k gui/$(id -u)/com.clawmetry.sync # restart after an editSet 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#
[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=truesupervisorctl reread && supervisorctl update
supervisorctl status clawmetry-syncContainers#
Run the daemon as the container's main process and the dashboard alongside it, or in a second container sharing the state volume.
→ Docker
Restarting safely#
clawmetry sync --restartThis 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.
systemctl --user show clawmetry-sync -p ExecStart
ps -o command= -p "$(pgrep -f clawmetry.sync | head -1)"Verifying#
clawmetry status
curl -s localhost:8900/healthzA monitoring check that means something:
clawmetry status --json | jq -e '.daemon.running' >/dev/null