# systemd deployment (VPS) This is the primary deployment path (docker-compose is for local dev). ```bash sudo useradd -r -m -d /srv/cayce-ops cayce rsync -a --exclude .venv ./ cayce@vm:/srv/cayce-ops/ sudo -u cayce uv sync --frozen sudo -u cayce cayceops db upgrade # alembic to head sudo cp deploy/systemd/cayce-ops@.service deploy/systemd/cayce-ops@.timer /etc/systemd/system/ # Every daemon has a `run` subcommand now: # scanner run · executor run · maild run (poll + send-approved) # publisher run (publish-due) · monitor run (build) # cadence per daemon (edit OnCalendar in each timer copy): # scanner hourly executor */10 min maild */5 min # publisher */5 min monitor */1 min # NOTE: `publisher plan` (fills the calendar) is a SEPARATE timer: # OnCalendar=daily -> ExecStart=/srv/cayce-ops/.venv/bin/cayceops publisher plan for d in scanner executor maild publisher monitor; do sudo cp deploy/systemd/cayce-ops@.timer /etc/systemd/system/cayce-ops@$d.timer done # adjust OnCalendar per timer, then: sudo systemctl daemon-reload sudo systemctl enable --now cayce-ops@{scanner,executor,maild,publisher,monitor}.timer ``` The unit hardens the daemon (NoNewPrivileges, ProtectSystem=strict) and reads secrets only from `/srv/cayce-ops/.env` (never in the repo).