Halite is configured through environment variables at startup and through in-app settings stored in the database. This page covers both. For a guided walkthrough of the in-app Settings page, see Settings.Documentation Index
Fetch the complete documentation index at: https://www.halite-app.com/llms.txt
Use this file to discover all available pages before exploring further.
Environment variables
Set these in your.env file (which docker compose loads automatically) or pass them directly to the container.
Database
SQLAlchemy async database URL.For
compose.yml (Postgres): postgresql+asyncpg://halite:halite@db:5432/haliteFor compose.sqlite.yml (homelab): sqlite+aiosqlite:////data/halite.dbSessions
Signing key for session cookies. Must be at least 32 characters. Generate one with
./scripts/gen-bootstrap-secret.sh.How long a session remains valid after the last request, in minutes. Defaults to 480 (8 hours).
Controls the
Secure flag on the session cookie.false— cookie is sent over plain HTTP (use for local Docker testing athttp://localhost:8080)true— cookie is only sent over HTTPS (use in production behind a TLS proxy)
compose.yml profile defaults this to true; compose.sqlite.yml defaults it to false.Name of the session cookie.
Networking
The host address uvicorn binds to.
The shipped Docker images launch uvicorn with a hardcoded
--host 0.0.0.0 --port 8080, so this setting has no effect in the provided compose setups. To change the host port, remap the ports: entry in your compose file (e.g. "9000:8080").The port uvicorn listens on.
The shipped Docker images launch uvicorn with a hardcoded
--host 0.0.0.0 --port 8080, so this setting has no effect in the provided compose setups. To change the host port, remap the ports: entry in your compose file (e.g. "9000:8080").Recognized by the settings loader but not currently wired into request handling. Reserved for future use.
Logging
Logging verbosity. Standard Python log level names:
debug, info, warning, error, critical.Audit
Recognized by the settings loader but not currently wired into request handling. Reserved for future use — intended to enable recording of read-only requests in the audit log, but the flag is not consumed anywhere in the current codebase.
SPA serving
Filesystem path to the built React SPA (
dist/). When set, the backend serves the SPA from this directory. When unset, SPA serving is disabled (useful if you serve the frontend separately).The provided Docker image sets this to /app/frontend/dist at build time.In-app settings (database-backed)
These settings are stored in a singletonAppSettings row in the database and managed on the Settings page. They are not environment variables — changing them does not require a container restart.
Salt-API connection
| Setting | Description | Default |
|---|---|---|
salt_api_url | URL of your salt-api (rest_cherrypy) endpoint | — |
salt_api_username | Username for Salt-API authentication | — |
salt_api_password_encrypted | Salt-API password, encrypted at rest using COOKIE_SECRET | — |
salt_api_verify | Whether to verify the Salt-API TLS certificate | true |
salt_api_eauth | eauth backend (e.g. pam, ldap) | "pam" |
The Salt-API connection is configured entirely through the in-app Settings page. The
SALT_API_* lines in .env.example are stale placeholders not read by current builds.Inventory refresh
| Setting | Description | Default |
|---|---|---|
inventory_refresh_minutes | Run a background refresh_packages(target='*') every N minutes. 0 disables it; manual refreshes still work. | 0 |
inventory_refresh_initial_delay_s | Seconds before the first scheduled refresh fires after startup | 30 |
Pollers
| Setting | Description | Default |
|---|---|---|
fleet_poll_interval_seconds | Interval for fleet-state polling. 0 disables the poller. | 0 |
jobs_poll_interval_seconds | Interval for jobs polling. 0 disables the poller. | 0 |
minion_state_keys_interval_seconds | Interval for minion accepted-keys refresh | 300 |
minion_state_presence_interval_seconds | Interval for minion presence refresh | 60 |
minion_state_grains_interval_seconds | Interval for minion grains refresh | 300 |
minion_state_initial_delay_seconds | Startup delay before the first minion-state poll | 10 |
Logging format
| Setting | Description | Default |
|---|---|---|
log_format | Log output format: json (structured) or text (human-readable) | "json" |
The application startup currently calls
setup_logging with a hardcoded "json" value, so current builds always emit JSON logs regardless of the log_format setting. The LOG_FORMAT entry in .env.example is stale and not read by the application.Bootstrap admin
On first boot, when no users exist in the database, Halite automatically creates a default admin account:- Username:
admin - Password:
changeme - Forced password change: Yes — you are required to set a new password on first login.
bootstrap.py. The BOOTSTRAP_ADMIN_USERNAME and BOOTSTRAP_ADMIN_PASSWORD lines in .env.example are stale and not read by the application.
Stale .env.example entries
The following entries appear in .env.example but are not read by the application in current builds:
| Entry | Actual location |
|---|---|
BOOTSTRAP_ADMIN_USERNAME / BOOTSTRAP_ADMIN_PASSWORD | Hardcoded in bootstrap.py |
SALT_API_* | In-app Settings page (DB-backed) |
INVENTORY_REFRESH_MINUTES / INVENTORY_REFRESH_INITIAL_DELAY_S | In-app Settings page (DB-backed) |
LOG_FORMAT | In-app Settings page (DB-backed) |