.env file or from the process environment (Docker Compose environment: section). The frontend reads a single variable at runtime — no rebuild needed.
Backend variables
Create a.env file in the backend/ directory by copying the example:
Optional — data sources
All backend variables are optional. The backend starts cleanly without any of them, but missing keys degrade specific data layers. A startup warning is logged for each missing key.| Variable | Description | Effect if missing |
|---|---|---|
AIS_API_KEY | WebSocket API key for AISStream.io real-time vessel tracking. | Ships layer is empty. |
OPENSKY_CLIENT_ID | OAuth2 client ID for OpenSky Network. Provides flight gap-fill in Africa, Asia, and Latin America. | Flight coverage reduced outside ADS-B Exchange range. |
OPENSKY_CLIENT_SECRET | OAuth2 client secret paired with OPENSKY_CLIENT_ID. Both must be set together. | Same as above. |
LTA_ACCOUNT_KEY | Account key for Singapore’s Land Transport Authority API. Enables the Singapore CCTV traffic camera layer. | Singapore CCTV layer is empty. |
Optional — security and networking
| Variable | Description | Default |
|---|---|---|
ADMIN_KEY | Secret key that protects the /api/settings/api-keys, /api/settings/news-feeds, and /api/system/update endpoints. Pass it in the X-Admin-Key request header. If unset, those endpoints are open to anyone who can reach the backend — acceptable for local dev, not for production. | Unset (endpoints unprotected) |
CORS_ORIGINS | Comma-separated list of allowed CORS origins. By default the backend auto-detects localhost and the machine’s LAN IPs. Override this when your frontend is on a different host or port. | Auto-detected localhost + LAN IPs |
Frontend variables
The frontend reads one variable at runtime — it does not need to be baked in at build time (it is not aNEXT_PUBLIC_* build-time variable). Set it in the root .env file used by Docker Compose, or in the container’s environment directly.
| Variable | Description | Default |
|---|---|---|
BACKEND_URL | Full URL of the backend that the Next.js server uses to proxy /api/* requests (e.g., http://backend:8000 in Docker, http://192.168.1.50:8000 for a remote host). The browser only ever talks to the frontend on port 3000 — port 8000 does not need to be exposed externally. | http://backend:8000 (Docker internal) / http://localhost:8000 (local dev) |
Setting variables
In a .env file
For local development, add variables to the appropriate.env file:
backend/.env
In Docker Compose
Pass variables via theenvironment: section in your compose.yml:
compose.yml
compose.yml
At runtime (frontend)
BecauseBACKEND_URL is a runtime variable (not baked in at build time), you can update it without rebuilding the frontend image:
.env file next to docker-compose.yml:
.env
Docker Swarm secrets
All backend variables support a_FILE variant for use with Docker Swarm secrets. When <VAR>_FILE is set, the backend reads the file at that path and loads its contents into <VAR> before any service code runs.
The following variables support the _FILE suffix:
AIS_API_KEY_FILEOPENSKY_CLIENT_ID_FILEOPENSKY_CLIENT_SECRET_FILELTA_ACCOUNT_KEY_FILECORS_ORIGINS_FILEADMIN_KEY_FILE
compose.yml
The
_FILE loading runs before any service module is imported, so secrets are available to all Python code that reads os.environ at import time.Startup validation
At startup, the backend callsvalidate_env() and logs the status of every variable. There are no hard-required variables — the app always starts — but two severity levels are used:
- Critical warning —
ADMIN_KEYis missing: logged atCRITICALlevel. The backend starts, but sensitive endpoints (/api/settings/*,/api/system/update) are unprotected and open to any request. - Optional warning —
AIS_API_KEY,OPENSKY_CLIENT_ID,OPENSKY_CLIENT_SECRET, orLTA_ACCOUNT_KEYis missing: logged atWARNINGlevel. The affected data layer will be empty or reduced.