{ "groups": { "server": "Server", "https": "HTTPS", "database": "Database", "secrets": "Secrets", "auth": "Sign in", "proxy": "Proxies and origins", "logging": "Logs and audit", "plugins": "Plugins", "desktop": "Desktop app", "internal": "Internal" }, "vars": [ { "name": "PORT", "group": "server", "default": "8080", "description": "Port the web UI listens on in the Docker image." }, { "name": "DATA_DIR", "group": "server", "default": "/app/data", "description": "Where Termix keeps its database, keys, plugins and uploads. Mount a volume here. Outside Docker the default is ./db/data." }, { "name": "ALLOW_EMPTY_DATA_DIR", "group": "server", "default": "false", "description": "Start even when DATA_DIR is empty but an older data folder exists elsewhere. Only set this if you really want a fresh install." }, { "name": "PUID", "group": "server", "default": "1000", "docker": true, "description": "User id the container runs as. Match it to the owner of your data volume." }, { "name": "PGID", "group": "server", "default": "1000", "docker": true, "description": "Group id the container runs as." }, { "name": "BASE_PATH", "group": "server", "description": "Serve Termix under a sub path, like /termix. Set the same path in your reverse proxy." }, { "name": "NODE_ENV", "group": "server", "default": "production", "description": "Set by the image. Leave it alone." }, { "name": "VERSION", "group": "server", "description": "Set by the image to the Termix version. Leave it alone." }, { "name": "SETTINGS_CACHE_REFRESH_SECONDS", "group": "server", "default": "30", "description": "How often each server instance reloads admin settings from the database. 0 turns the refresh off." }, { "name": "SSH_AUTH_SOCK", "group": "server", "description": "SSH agent socket used for hosts set to agent auth when they do not name their own socket." }, { "name": "ENABLE_SSL", "group": "https", "default": "false", "description": "Serve HTTPS. Termix makes a self-signed certificate on first boot unless you give it one." }, { "name": "SSL_PORT", "group": "https", "default": "8443", "description": "Port for HTTPS." }, { "name": "SSL_CERT_PATH", "group": "https", "default": "/app/data/ssl/termix.crt", "description": "Certificate file for HTTPS." }, { "name": "SSL_KEY_PATH", "group": "https", "default": "/app/data/ssl/termix.key", "description": "Private key file for HTTPS." }, { "name": "SSL_DOMAIN", "group": "https", "default": "localhost", "description": "Domain put in the self-signed certificate." }, { "name": "TERMIX_SSL_TERMINATED_BY_NGINX", "group": "https", "internal": true, "description": "Set by the image when nginx serves HTTPS in front of the backend." }, { "name": "DATABASE_DIALECT", "group": "database", "default": "sqlite", "description": "sqlite, postgres or mysql." }, { "name": "DATABASE_URL", "group": "database", "description": "Connection URL for postgres or mysql, like postgres://user:pass@db:5432/termix." }, { "name": "DATABASE_POOL_MAX", "group": "database", "default": "10", "description": "Most connections Termix opens to postgres or mysql." }, { "name": "DATABASE_SSL", "group": "database", "description": "TLS for postgres or mysql: require, no-verify or disable." }, { "name": "DB_FILE_ENCRYPTION", "group": "database", "default": "true", "description": "Encrypt the SQLite file at rest. Set false only if something else already encrypts the disk." }, { "name": "DB_FILE_KEY", "group": "database", "secret": true, "description": "Only used to open SQLite files encrypted by very old versions. You almost never need it." }, { "name": "DATABASE_LAYER_SKIP_PREUPGRADE_BACKUP", "group": "database", "default": "false", "description": "Skip the backup Termix takes of the data folder before an upgrade changes the database." }, { "name": "DATABASE_LAYER_PREUPGRADE_BACKUP_KEEP", "group": "database", "default": "3", "description": "How many of those upgrade backups to keep." }, { "name": "DRIZZLE_MIGRATIONS_DIR", "group": "database", "internal": true, "description": "Where database migrations are read from. Set by the image." }, { "name": "JWT_SECRET", "group": "secrets", "secret": true, "description": "Signs sign-in sessions. At least 64 characters. Made for you and saved in DATA_DIR/.env if not set. Also read from JWT_SECRET_FILE." }, { "name": "DATABASE_KEY", "group": "secrets", "secret": true, "description": "Key for the encrypted SQLite file, 64 hex characters. Made for you if not set. Also read from DATABASE_KEY_FILE." }, { "name": "ENCRYPTION_KEY", "group": "secrets", "secret": true, "description": "Wraps the data keys that encrypt passwords and SSH keys, 64 hex characters. Made for you if not set. Also read from ENCRYPTION_KEY_FILE." }, { "name": "INTERNAL_AUTH_TOKEN", "group": "secrets", "secret": true, "description": "Token the server uses to call itself. Made for you if not set. Also read from INTERNAL_AUTH_TOKEN_FILE." }, { "name": "TERMIX_REQUIRE_EXTERNAL_SECRETS", "group": "secrets", "default": "false", "description": "Refuse to start unless the four secrets above come from env vars or _FILE files, so none are written to disk." }, { "name": "OIDC_SYSTEM_SECRET", "group": "secrets", "secret": true, "description": "Only read to move data from installs older than 2.5. Never change it on an install that has it." }, { "name": "WEBAUTHN_SYSTEM_SECRET", "group": "secrets", "secret": true, "description": "Only read to move data from installs older than 2.5. Never change it on an install that has it." }, { "name": "ALLOW_PASSWORD_LOGIN", "group": "auth", "description": "true or false. Overrides the admin setting for signing in with a username and password." }, { "name": "ALLOW_REGISTRATION", "group": "auth", "description": "true or false. Overrides the admin setting for creating new accounts." }, { "name": "ALLOW_PASSWORD_RESET", "group": "auth", "description": "true or false. Overrides the admin setting for resetting a password from the sign in page." }, { "name": "EXTERNAL_ALLOW_REGISTRATION", "group": "auth", "description": "true or false. Overrides the admin setting for creating accounts the first time someone signs in with SSO or LDAP." }, { "name": "EXTERNAL_FORCE_HTTPS", "group": "auth", "default": "false", "description": "Build sign in callback URLs with https even when the request came in over http. Use it behind a proxy that does not send X-Forwarded-Proto." }, { "name": "OIDC_ALLOW_REGISTRATION", "group": "auth", "deprecated": "EXTERNAL_ALLOW_REGISTRATION", "description": "Old name for EXTERNAL_ALLOW_REGISTRATION. Still read in 26.10." }, { "name": "OIDC_FORCE_HTTPS", "group": "auth", "deprecated": "EXTERNAL_FORCE_HTTPS", "description": "Old name for EXTERNAL_FORCE_HTTPS. Still read in 26.10." }, { "name": "OIDC_CLIENT_ID", "group": "auth", "internal": true, "description": "Read by core only to move a 2.8 OIDC setup into the sso plugin. See the sso plugin for the real variables." }, { "name": "OIDC_ENV_OVERRIDE", "group": "auth", "internal": true, "description": "Read by core only to move a 2.8 OIDC setup into the sso plugin. See the sso plugin for the real variables." }, { "name": "TRUSTED_PROXY_AUTH_ENABLED", "group": "auth", "default": "false", "description": "Let a proxy like Authelia or Authentik sign people in by sending their username in a header." }, { "name": "TRUSTED_PROXY_AUTH_TRUSTED_PROXIES", "group": "auth", "description": "Comma separated IPs or CIDRs of the proxies allowed to send the headers. Required when trusted proxy login is on." }, { "name": "TRUSTED_PROXY_AUTH_USERNAME_HEADER", "group": "auth", "default": "x-forwarded-username", "description": "Header that holds the username." }, { "name": "TRUSTED_PROXY_AUTH_ROLE_HEADER", "group": "auth", "default": "x-forwarded-role", "description": "Header that holds the user's groups or roles." }, { "name": "TRUSTED_PROXY_AUTH_ROLE_MAP", "group": "auth", "description": "JSON map from proxy roles to Termix roles, like {\"admins\":[\"admin\"],\"staff\":[\"user\"]}. Required when trusted proxy login is on." }, { "name": "TRUSTED_PROXIES", "group": "proxy", "docker": true, "description": "Comma separated IPs or CIDRs nginx takes the client IP from (X-Forwarded-For). Set it to your reverse proxy." }, { "name": "CORS_ALLOWED_ORIGINS", "group": "proxy", "description": "Comma separated extra origins allowed to call the API from a browser." }, { "name": "TERMIX_ALLOWED_ORIGINS", "group": "proxy", "description": "Comma separated extra origins allowed to open WebSockets." }, { "name": "HTTP_PROXY", "group": "proxy", "description": "Proxy for outbound HTTP requests, like registry downloads and webhooks." }, { "name": "HTTPS_PROXY", "group": "proxy", "description": "Proxy for outbound HTTPS requests." }, { "name": "NO_PROXY", "group": "proxy", "description": "Comma separated hosts that skip the proxy." }, { "name": "LOG_LEVEL", "group": "logging", "default": "info", "description": "debug, info, warn or error." }, { "name": "LOG_TIMESTAMP_FORMAT", "group": "logging", "description": "iso or 24h. Unset uses the local time format." }, { "name": "AUDIT_LOG_RETENTION_DAYS", "group": "logging", "description": "Delete audit entries older than this many days. Unset keeps them until the entry cap." }, { "name": "AUDIT_LOG_MAX_ENTRIES", "group": "logging", "default": "10000", "description": "Most audit entries kept. The oldest go first." }, { "name": "AUDIT_LOG_FORWARD_URL", "group": "logging", "description": "Also POST every audit entry as JSON to this URL. Overrides the admin setting." }, { "name": "AUDIT_LOG_FORWARD_TOKEN", "group": "logging", "secret": true, "description": "Bearer token sent with forwarded audit entries." }, { "name": "SESSION_RECORDING_RETENTION_DAYS", "group": "logging", "deprecated": "the session-recording plugin setting", "description": "Only read once to carry a 2.8 value into the session-recording plugin." }, { "name": "TERMIX_PLUGIN_REGISTRY_URL", "group": "plugins", "description": "Use another plugin index instead of the official registry." }, { "name": "TERMIX_PLUGIN_STATS_URL", "group": "plugins", "description": "Where install counts are read from. Defaults to stats.json next to the registry index." }, { "name": "TERMIX_REQUIRE_SIGNED_PLUGINS", "group": "plugins", "default": "false", "description": "Only load plugins signed by a trusted key. Blocks uploads of unsigned files even in developer mode." }, { "name": "TERMIX_BUNDLED_PLUGINS_DIR", "group": "plugins", "description": "Where the plugins shipped with Termix are read from. Set by the image." }, { "name": "TERMIX_PLUGIN_PUBLIC_RATE_LIMIT", "group": "plugins", "default": "120", "description": "Requests per minute one IP may make to a plugin's public routes." }, { "name": "PLUGIN_MAX_KV_KEYS", "group": "plugins", "default": "10000", "description": "Most key value entries one plugin may store." }, { "name": "TERMIX_DEV_RELOAD", "group": "plugins", "internal": true, "description": "Set by npm run dev so plugin rebuilds reload without a restart." }, { "name": "TERMIX_DEV_RUNNER", "group": "plugins", "internal": true, "description": "Set by npm run dev." }, { "name": "ENABLE_INSECURE_MODE", "group": "desktop", "default": "false", "description": "Desktop app only. Skip TLS certificate checks for the linked server. Only for testing." }, { "name": "ELECTRON_DISABLE_GPU", "group": "desktop", "description": "Desktop app only. Set to 1 to turn off GPU acceleration if the window is blank or flickers." }, { "name": "TERMIX_LOCAL_SHELL", "group": "desktop", "description": "Desktop app only. Shell the local terminal opens, like /bin/zsh or pwsh.exe." }, { "name": "SHELL", "group": "desktop", "internal": true, "description": "Your login shell, used by the local terminal when TERMIX_LOCAL_SHELL is not set." }, { "name": "ELECTRON_EMBEDDED", "group": "desktop", "internal": true, "description": "Set by the desktop app when it runs its own backend." }, { "name": "TERMIX_DATA_DIR", "group": "desktop", "internal": true, "description": "Set by the desktop app to its data folder." }, { "name": "XDG_CURRENT_DESKTOP", "group": "desktop", "internal": true, "description": "Read on Linux to pick the password store and window behavior." }, { "name": "DESKTOP_SESSION", "group": "desktop", "internal": true, "description": "Read on Linux to pick the password store." }, { "name": "VITE_BASE_PATH", "group": "internal", "internal": true, "description": "Base path baked in at build time." } ] }