.NET Engine — Configuration
The engine reads its configuration from .env in its install directory. Only
LICENSE is required.
Settings
| Key | Default | What 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
| Key | What 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
- Prints its build identifier and feature list — useful when confirming which binary is deployed.
- Hardens itself: marks the process non-dumpable and sets
RLIMIT_CORE=0, so decrypted tenant assemblies cannot appear in a core dump. - Reads
LICENSE. Exits with status1if absent. - Reports its seal state to the control plane.
- Fetches and builds every application assigned to it, then reports how many hosts are ready.
- Binds
PORTand 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
sudo systemctl restart lf-engine sudo journalctl -u lf-engine -f