Documentation

Deployment

Everlock is one self-contained binary with the model embedded — nothing to assemble, no runtime dependencies, and storage is always just filesystem access: a single data directory of git-backed files, never a database. So deploying it comes down to how you supervise the process, bind its ports, and hold that data directory. Start from the table; the same binary and the same on-disk data work under all three, so you can move up later without migrating anything.

📦 Standalone🐳 Docker⚙️ systemd
Best fortrying it outcontainer-only platformsproduction
Update restart⚠️ brief dropcontainer restart✅ graceful
Privileged portsroot / capability-p mappings✅ unprivileged
Storageany directorymounted volume✅ isolated
Supervision & logs—platform✅ built-in
mDNS / .localworks⚠️ needs host networkworks

Standalone binary

Download the build for your platform, then point it at a data directory and start it — ideal for development and for trying things out. Storage is wherever --data-dir points. The download page lists every build; all of them embed the same model — see the embedded model.

curl -fL https://everlock.sh/dl/latest/everlock-linux-amd64 -o everlock
chmod +x everlock
./everlock serve --data-dir ./data --frontend-http --frontend-ssh

Binding privileged ports (80, 443, 25, …) means running as root or granting CAP_NET_BIND_SERVICE, and a self-update swaps the binary and re-execs in place, dropping in-flight connections for the ~1–2 s it takes to rebind. Getting started walks this path from first run to publishing content.

Docker container

For platforms that only run containers — orchestrators, container-native hosts — a scratch-based multi-arch image is published at cr.everlock.sh/everlock. It wraps the same binary; on a native host, the downloaded binary (standalone or under systemd) is the primary path. The data directory lives in a mounted volume (/data).

docker run -d --name everlock \
  -p 80:80 -p 443:443 -p 2222:2222 \
  -v everlock-data:/data \
  cr.everlock.sh/everlock:latest

The image listens on 80 and 443 — the binary defaults to 8080 for the native case, where binding 80 needs root, and the container has no such constraint. Move a listener with the same setting as configuration, e.g. -e EVERLOCK_FRONTEND_HTTP_LISTEN_HTTP=0.0.0.0:8080.

Map each service's ports with -p; a restart is a container restart. docker run -P is the wrong tool here — it assigns random host ports, and for SMTP, DNS, IMAPS and ACME the port number is the contract.

Auto-update is off in the image — containers update by pulling a new tag (docker pull, then recreate), not by rewriting their own binary; set -e EVERLOCK_UPDATE_ENABLED=true only if you deliberately want in-container updates.

Discovery needs --network=host. mDNS (.local) and SSDP both rely on multicast, which does not cross Docker's default bridge, and the SSDP device description is served from a port picked at startup that no port mapping can name in advance.

On a native Linux host, run Everlock as a systemd service with socket activation — systemd binds the listening sockets and hands them to the process. That, plus a managed state directory, is what earns the ✅ marks above:

  • Graceful restarts. systemd owns the sockets, so a restart — self-update, admin change, or systemctl restart — drains in-flight requests, exits, and lets systemd re-hand the same socket to the new process. Waiting connections queue instead of being refused.
  • An unprivileged process. systemd binds the low ports (80, 443, 25, 587, 993, and DNS on 53) before the service starts, so Everlock runs as an ordinary user with no capabilities.
  • Isolated storage. StateDirectory gives the service its own /var/lib/everlock, owned by the service user, and the unit's sandboxing (ProtectSystem, ProtectHome, PrivateTmp) keeps it from touching anything else on the host.
  • Supervision and logs. Restart=always recovers from a crash or a self-update exit, and output goes to the journal.

This is the deployment the self-update and restart machinery was built for. The full setup — a socket unit per port, the service unit, and the graceful hand-off — is in systemd with socket activation.