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 & logsplatform✅ 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; the smolvlm / qwen3 segment picks the embedded AI model, which decides the AI runtime's capabilities — see AI model variants.

curl -fL https://everlock.sh/dl/latest/qwen3/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

Map each service's ports with -p; a restart is a container restart. 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. One more caveat: mDNS (.local discovery) needs --network=host, because multicast does not cross Docker's default bridge.

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.