Documentation menu
Server deployment
The control plane is a single Go binary shipped as a distroless container. It expects a reverse proxy to terminate mTLS and never publishes port 9520 by itself.
Requirements
- A Linux host with Docker 24+ (the example Compose file), or Go 1.22+ to build from source.
- A reverse proxy that can verify client certificates: Nginx, Nginx Proxy Manager or Caddy.
- A private Docker network shared only by the proxy and the control plane.
Pull and run
docker pull ghcr.io/molirain/molisync-server:latest
cp docker-compose.example.yml docker-compose.yml
docker compose up -d
docker compose ps
The image is multi-arch (linux/amd64, linux/arm64), runs as nonroot and contains no shell or package manager.
The example Compose file does not publish port 9520. Do not add a host port mapping; join your existing reverse proxy to the molisync-internal network instead.
Configuration
Every setting can be passed as an environment variable; a YAML file works too, and environment variables win over the file.
| Variable | Purpose |
|---|---|
MOLISYNC_SERVER_LISTEN | Listen address. Defaults to 0.0.0.0:9520 inside the image. |
MOLISYNC_PROXY_TRUSTED_CIDRS | Proxy networks allowed to assert an identity. Must match the Compose subnet. |
MOLISYNC_PROXY_VERIFY_HEADER | Header carrying the verified result. |
MOLISYNC_PROXY_FINGERPRINT_HEADER | Header carrying the certificate fingerprint. |
MOLISYNC_PROXY_DN_HEADER | Header carrying the certificate subject. |
MOLISYNC_AUTH_DEVICE_ID_SOURCE | fingerprint (recommended) or dn_cn. |
MOLISYNC_STORAGE_DATA_DIR | SQLite database and blob root. Defaults to /var/lib/molisync. |
MOLISYNC_STORAGE_MAX_ITEM_BYTES | Maximum uploaded blob size. Default 64 MiB. |
MOLISYNC_LOG_LEVEL / ..._FORMAT | debug|info|warn|error and json|text. |
Health and data
The image health check calls the binary's -healthcheck-url probe against http://127.0.0.1:9520/healthz. If you change the listen port, override the Compose health check too.
Records and blobs live in the molisync-data volume. Back up the SQLite database and the blobs/ directory together; deleting the volume deletes every synced record.
Build locally
cd server
docker build -t molisync-server:dev .
docker run --rm -p 127.0.0.1:9520:9520 \
-e MOLISYNC_PROXY_TRUSTED_CIDRS=127.0.0.1/32 \
molisync-server:dev