Deployment wrapper for Leon, the open-source personal assistant, built for Railway.
Upstream publishes no container image, so this repository builds Leon from its
last stable release tag (v1.0.0-beta.8) and adds what a hosted deployment
needs.
| Why | |
|---|---|
Caddy gateway on $PORT |
Leon ships with no authentication on its web app or its socket.io channel. The gateway puts HTTP basic auth in front of every route, so the assistant is not open to whoever finds the URL. Basic auth specifically, because the browser replays it on the app's own same-origin XHR and socket.io polling. |
Anonymous /healthz |
Replayed to Leon's own /api/v1/info, so the health check exercises the app rather than the proxy. Every other route is authenticated. |
| cgroup-aware thread sizing | Leon's NLP tier runs spaCy's en_core_web_trf on PyTorch, which sizes its OpenMP pool from the host's core count (48 on Railway) and exposes no in-app knob. The entrypoint derives the cap from cpu.max. |
| Volume wiring | Leon keeps state in place — each skill's TinyDB lives at skills/<domain>/<skill>/memory/db.json, downloads in downloads/. Railway volumes are 1:1 with a service, so the entrypoint seeds each directory once and symlinks it onto the single mount. |
| No baked credential | Leon's installer writes a generated HTTP API key into .env at build time. The build blanks it; the key comes from a Railway variable instead. |
| Variable | Default | Notes |
|---|---|---|
LEON_BASIC_AUTH_PASSWORD |
— | Required. Gateway password. The container refuses to start without it. |
LEON_BASIC_AUTH_USER |
leon |
Gateway username. |
LEON_HTTP_API_KEY |
(empty) | Sent as X-API-Key to POST /api/query. With none set, that endpoint answers 401 to everything. |
PORT |
8080 |
Set by Railway. The gateway binds it. |
LEON_INTERNAL_PORT |
1337 |
Loopback port Leon itself listens on. Not exposed. |
LEON_LANG |
en-US |
en-US or fr-FR. Selects the spaCy model the TCP server loads. |
LEON_TELEMETRY |
true upstream |
Set false to stop Leon reporting usage and errors to its telemetry service. |
LEON_OVER_HTTP |
true |
Enables POST /api/query. |
LEON_STT / LEON_TTS |
false |
Offline speech needs models this image does not ship; the cloud providers need their own credentials. |
LEON_AFTER_SPEECH |
false |
Re-open the mic after Leon speaks. |
LEON_TIME_ZONE |
(host) | IANA name, e.g. Europe/Paris. |
docker build -t leon-railway .
docker run --rm -p 8080:8080 -e LEON_BASIC_AUTH_PASSWORD=change-me leon-railwayThe build downloads roughly 1.4 GB of release binaries (the Python bridge and the PyInstaller TCP server, which carries the spaCy model), so expect it to take a while and to produce a large image.
Leon is MIT-licensed by Louis Grenard. This wrapper carries no upstream source.