Skip to main content
This guide covers running Celly as a long-lived service on a Linux host with systemd --user. As on Windows, the bot must run as the user who owns the sbx daemon and its credentials.

1. Host bootstrap

  1. Install sbx (Docker Sandboxes), then log in and initialize the network policy:
    Celly targets sbx >= 0.45.0.
  2. Install Node 24 with fnm (or nvm):
  3. Register provider credentials used by the sandboxed agent (see Providers):

2. Build and configure

3. systemd user service

Create ~/.config/systemd/user/celly.service:
bash -lc loads your shell profile so fnm/nvm and sbx are on PATH; exec keeps Node as the main process so SIGTERM reaches Celly’s shutdown handler. Enable it and keep it running after logout:

4. Backups and log rotation

Celly backs up DATA_DIR/bot.db with SQLite VACUUM INTO on an interval and prunes old copies. It also rotates bot.log and every per-project server log. Backups are named data/backups/bot-<ISO>.db. To restore one, stop the service, replace the database, and start it again:

5. Admin page (optional)

Set ADMIN_PORT (default 4560, 0 disables) to serve a loopback-only status page and JSON API:
  • GET / — HTML status page
  • GET /api/projects, GET /api/health
  • POST /api/projects/<channelId>/start|stop
  • GET /api/logs/<channelId>?lines=200 — redacted log tail
  • GET /api/audit?limit=100 — when the audit log is enabled
It binds 127.0.0.1 only and has no authentication: reach it through an SSH tunnel (ssh -L 4560:127.0.0.1:4560 host) and never expose the port.

6. Verifying a deployment

  • sbx diagnose reports a healthy daemon and authentication.
  • systemctl --user status celly is active (running).
  • curl -s http://127.0.0.1:4560/api/health returns {"ok":true,...}.
  • data/bot.log shows the preflight passing and the Discord client logging in.

7. Troubleshooting