LockFlare

.NET Engine — Configuration

The engine reads its configuration from .env in its install directory. Only LICENSE is required.

Settings

KeyDefaultWhat it does
LICENSE required The server’s licence key, bound to its IP address. The engine exits immediately without it.
PORT 80 The HTTP port the engine binds directly. There is no reverse proxy.
LF_TLS off Set to 1 to terminate TLS on this server.
LF_TLS_PORT 443 The HTTPS port, when TLS is enabled.
LF_TLS_DIR /etc/lockflare/certs Where certificates are read from. Falls back to /etc/letsencrypt/live.
LF_ACME_DIR /var/lib/lockflare/acme Webroot for ACME challenges during certificate issuance and renewal.
LF_DIR working directory Where locally-stored encrypted builds are kept, as lfapp-<appKey>.lfb.
LF_READY_TIMEOUT_SEC How long the supervisor waits for a tenant process to report ready before treating the start as failed.

Isolation controls

KeyWhat it does
LF_SPAWN Path to the privileged helper that joins the cgroup, unshares namespaces and drops privileges before your code runs.
LF_ALLOW_UNCONFINED Permits an application to start when confinement could not be established.
Leave LF_ALLOW_UNCONFINED unset in production. With it unset, an application whose namespaces, cgroup or dedicated user could not be established refuses to start — which is the behaviour you want, because the alternative is a tenant running with the host’s view of processes and files. It exists for diagnosing a confinement failure, not for working around one.

What the engine does at startup

  1. Prints its build identifier and feature list — useful when confirming which binary is deployed.
  2. Hardens itself: marks the process non-dumpable and sets RLIMIT_CORE=0, so decrypted tenant assemblies cannot appear in a core dump.
  3. Reads LICENSE. Exits with status 1 if absent.
  4. Reports its seal state to the control plane.
  5. Fetches and builds every application assigned to it, then reports how many hosts are ready.
  6. Binds PORT and starts serving.

Per-application limits

Each application runs under a cgroup with a memory ceiling and a process cap, created fresh on every launch. An application that exceeds its memory cap is killed and restarted rather than being allowed to exhaust the host.

If a previous generation’s cgroup cannot be drained, the engine refuses to restart that application rather than starting a second copy against a stale limit. That appears in the log as refusing restart: previous generation could not be terminated.

Applying changes

after editing .env
sudo systemctl restart lf-engine
sudo journalctl -u lf-engine -f