Skip to content
MoliSync
Documentation menu
Documentation Operations

Operations & security

Run the control plane like a stateful service: one volume, a narrow network and a proxy that owns the trust boundary.

Data and backup

  • molisync-data holds SQLite metadata and the blobs/ directory.
  • Records do not expire automatically, and there is no quota yet.
  • Only the sender can delete a record.
  • Back up the database and blobs together, ideally while the service is stopped or quiesced.

Logs and health

MOLISYNC_LOG_LEVEL accepts debug, info, warn and error; MOLISYNC_LOG_FORMAT selects json or text. The container probes /healthz through the server binary because the image has no curl.

Hardening checklist

  • Container runs nonroot with a read-only root filesystem, no added capabilities and no-new-privileges.
  • Only the proxy joins molisync-internal; port 9520 stays unpublished.
  • MOLISYNC_PROXY_TRUSTED_CIDRS is as narrow as possible.
  • Client private keys stay in the operating system certificate stores.
  • Android requires HTTPS and can pin a private CA.

Upgrades and versions

docker compose pull
docker compose up -d
docker compose ps

Components share a MAJOR.MINOR baseline while each keeps its own PATCH number. Release tags are per component: server-v0.5.1 builds only the server image, desktop-v0.5.1 publishes only the portable archive and android-v0.5.1 only the APK. There is no umbrella v* tag, so fixing one client never publishes everything.

Images are tagged latest, X.Y.Z and sha-<commit>. Pin a version tag if you need reproducible rollouts, and back up the volume before upgrading. The server checks the server-v namespace every 12 hours and forwards the result through /api/v1/me, which is how clients warn that the server itself is behind.

Usage statistics

  • Rule: a device reports once, the first time it connects; reconnects send nothing. No periodic heartbeat, no client-side analytics.
  • The event holds only a deployment-scoped hashed id, the platform and the version. The id derives from "deployment id + salted device key", so it is unlinkable across deployments and the Worker never sees a fingerprint, name or IP.
  • The counter is the project-operated public endpoint statistics-api.molirain.com (Cloudflare Worker + D1, deployed from a separate repository).
  • GET /stats requires ADMIN_TOKEN and returns 503 when it is unset; ?format=text prints installations, deployments and the platform split.
  • Use deployments as the headcount (one server per owner); installations counts devices, so one person with two clients inflates it.
  • telemetry.endpoint is empty by default, which keeps reporting off; MOLISYNC_TELEMETRY_ENABLED=false disables it entirely.

Known limits

  • No automatic record cleanup and no quota.
  • Update prompts read GitHub Releases anonymously, so the repository must be public; otherwise clients stay silent.
  • End-to-end P2P still needs real-network regression.
  • No repository-wide license has been declared.