Deploy dccd on a server (run it unattended)

Run dccd start (scheduler + streams + web UI) 24/7 on a server, surviving crashes and reboots. Two blessed paths are below; systemd is recommended for a long-lived home/VPS box (no container overhead, journald integration, clean restart semantics). Use Docker for a containerised or ephemeral host.

Both were verified end to end on a real Ubuntu 24.04 server.

Note

Old CPUs without AVX2 (common on recycled home servers): the default polars wheel crashes the daemon at import with SIGILL. Check with grep -o -m1 avx2 /proc/cpuinfo — if it prints nothing, use the polars-lts-cpu variant (shown in both paths below).

Operate it

  • Health: GET /health returns 200 when up. The systemd unit restarts on failure; the Docker image ships a HEALTHCHECK so an orchestrator sees healthy/unhealthy.

  • Logs & rotation: dccd writes no log files — logs go to the journal (journalctl -u dccd). Rotation is journald’s job (/etc/systemd/journald.conf: SystemMaxUse=, MaxRetentionSec=). Under Docker, the container engine owns rotation (--log-opt max-size=…).

  • Alerts: set alerts.webhook_url (and alerts.max_consecutive_errors) to POST a webhook when a job fails repeatedly. Verified: a failing job past the threshold delivers the alert.

  • Resource limits: the unit ships commented MemoryMax/CPUQuota/TasksMax — uncomment and tune for your host (too-low values can OOM-kill a busy daemon).

  • Secrets: keep the token out of the image/VCS — see Protect the web UI with a token.

  • Off-box backups: mirror the store with rclone — see Sync data to a remote (S3, GCS, …).

Alternative: Docker

# Build (add the build-arg only for a no-AVX2 host):
docker build -t dccd .
#   docker build --build-arg POLARS_VARIANT=polars-lts-cpu -t dccd .

# Run: mount the config (kept out of the image) + a named data volume.
docker run -d --name dccd --restart unless-stopped -p 8080:8080 \
    -v "$PWD/config.yml:/etc/dccd/config.yml:ro" \
    -v dccd-data:/data \
    dccd

The image is built on a digest-pinned python:3.12-slim, sets XDG_CONFIG_HOME=/etc (config at /etc/dccd/config.yml), exposes 8080, and declares a HEALTHCHECK against /health. Set settings.data_path: /data and settings.ui_host: 0.0.0.0 in the mounted config. Check docker inspect --format '{{.State.Health.Status}}' dccdhealthy.

Reaching the UI from another machine

The default bind is 127.0.0.1. To reach the UI remotely, set ui_host: 0.0.0.0 and a token (Protect the web UI with a token), and put it behind a private network (e.g. Tailscale) or a TLS reverse proxy — never expose the API plaintext on the public internet.