Files
2026-07-13 12:45:37 +08:00

135 lines
7.2 KiB
Bash

# Server encryption key for API key storage (generate with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))").
# Required in production. Outside production it is optional: when unset, a key is
# auto-generated and written to a file named .encryption-key next to the SQLite
# database (not inside it), with 0600 permissions. Precedence: this env var, then
# that key file, then a legacy key found in the old settings table (migrated to
# the file on first boot), then a freshly generated key.
ENCRYPTION_KEY=your-64-char-hex-key-here
# Server port (default: 3001)
PORT=3001
# Network interface the server listens on. Default '::' (dual-stack IPv4+IPv6);
# hosts with IPv6 disabled fall back to IPv4 automatically. Set 0.0.0.0 for
# IPv4-only or 127.0.0.1 to restrict to localhost. (Different from HOST_BIND
# below, which only affects Docker port publishing.)
# HOST=::
# First-run setup: the first account is created through the dashboard. A browser
# on the same machine as the server can do this with no extra step. If the server
# is reachable from other devices, creating that first account also requires a
# one-time setup code, printed in the server logs at startup while no account
# exists. This stops a stranger from claiming a freshly exposed install.
# Docker only: which host interface the container's port is published on.
# Defaults to 127.0.0.1, so the dashboard/API is reachable only from the
# machine running Docker. To open it to other devices on your LAN (e.g. a
# Raspberry Pi reached at http://192.168.1.x:3001), set HOST_BIND=0.0.0.0.
# Only do this on a trusted network — the proxy is single-user and guarded
# only by the unified API key.
# HOST_BIND=0.0.0.0
# Max /v1 proxy requests per minute per client IP (default: 120). Set to 0
# to disable proxy rate limiting.
# PROXY_RATE_LIMIT_RPM=120
# Per-provider daily request cap, named PROVIDER_DAILY_REQUEST_CAP_<PLATFORM>
# (platform name upper-cased). Overrides the built-in default for that provider;
# set to 0 to disable the cap. Example — cap OpenRouter at 50 requests/day:
# PROVIDER_DAILY_REQUEST_CAP_OPENROUTER=50
# Wall-clock budget for provider failover, in milliseconds (default: 45000).
# A request that keeps failing over stops STARTING new attempts once this much
# time has passed and returns the exhaustion error instead (the first attempt
# always runs; an in-flight attempt is never cut off). Set to 0 to disable and
# retry until the attempt cap. Can also be set at runtime via the
# fallback_time_budget_ms settings key, which takes precedence.
# FALLBACK_TIME_BUDGET_MS=45000
# Request guardrails, both OFF (0) by default. Also runtime-tunable via the
# request_max_tokens_budget / max_consecutive_upstream_fails settings keys
# (dashboard API PUT /api/settings/guardrails), which take precedence.
#
# Per-request token budget: estimated input + requested max_tokens must fit
# this ceiling or the request is rejected with a 413 before any provider is
# tried; a request that sent no max_tokens gets its output capped to the
# remainder instead.
# REQUEST_MAX_TOKENS_BUDGET=0
#
# Failover circuit breaker: after this many consecutive upstream failures in
# one request, stop the failover chain with a 503 instead of trying every
# remaining candidate of an unhealthy pool.
# MAX_CONSECUTIVE_UPSTREAM_FAILS=0
# Opt-in response cache. When on, a successful non-streaming /v1/chat/completions
# answer is stored in a bounded in-memory LRU keyed by a canonical hash of the
# request, so an IDENTICAL later request is served from memory without spending
# any provider quota. Exact match only (no fuzzy matching), so a near-miss never
# returns a different prompt's answer. Off by default; set to true to enable.
# Can also be toggled at runtime via the dashboard (PUT /api/cache/config), and
# per-request with the `X-FreeLLM-Cache: on|off` header. A restart flushes it.
# RESPONSE_CACHE=false
# How long a cached answer stays fresh, in seconds (default: 3600 = 1 hour).
# RESPONSE_CACHE_TTL_SECONDS=3600
# Only cache requests at/below this temperature; higher temperatures want fresh
# variety, so they are never cached. Default 1.0 caches everything when enabled;
# lower it (e.g. 0.2) to cache only near-deterministic calls.
# RESPONSE_CACHE_MAX_TEMPERATURE=1.0
# Hard cap on stored entries; the least-recently-used are evicted past this.
# RESPONSE_CACHE_MAX_ENTRIES=5000
# Custom-provider URL policy. Cloud metadata and link-local addresses
# (169.254.169.254, metadata.google.internal, fe80::/10, ...) are ALWAYS
# blocked as custom provider base URLs. By default localhost and private LAN
# addresses stay allowed so local Ollama / LM Studio / llama.cpp setups work.
# If you host FreeLLMAPI on a VPS or anywhere the dashboard is reachable by
# others, set this to also block loopback and RFC1918/ULA private ranges.
# FREEAPI_BLOCK_PRIVATE_PROVIDER_URLS=true
# Request analytics retention. Set either value to 0 to disable that limit.
REQUEST_ANALYTICS_RETENTION_DAYS=90
REQUEST_ANALYTICS_MAX_ROWS=100000
# Per-request caller identity (client IP + User-Agent) recorded into request
# analytics and shown in the dashboard's "Recent calls" table. Set to false
# to store nulls instead (aggregate analytics are unaffected).
# REQUEST_ANALYTICS_LOG_CLIENT=true
# Optional SQLite location. Useful on hosts where only one directory is mounted
# persistently, or when you want to keep the DB outside server/data.
# FREEAPI_DB_PATH=/app/server/data/freellmapi.db
# Optional encrypted SQLite backup. On startup, FreeLLMAPI restores this backup
# if the configured DB file is missing; while running, it uploads a fresh backup
# periodically. File paths and HTTP(S) URLs are supported.
# FREEAPI_DB_BACKUP_PATH=/app/server/data/freellmapi.db.backup
# FREEAPI_DB_BACKUP_URL=https://example.com/freellmapi.db.backup
# FREEAPI_DB_BACKUP_TOKEN=
# FREEAPI_DB_BACKUP_KEY=use-a-separate-64-char-hex-key-or-omit-to-use-ENCRYPTION_KEY
# FREEAPI_DB_BACKUP_INTERVAL_MS=300000
# Optional declarative startup config. Use either inline JSON or a path to a JSON
# file. It is applied idempotently after migrations on every boot.
# FREEAPI_CONFIG_PATH=/app/server/data/freellmapi.config.json
# FREEAPI_CONFIG_JSON={"keys":[{"platform":"groq","key":"gsk_...","label":"main"}],"routing":{"strategy":"balanced"}}
# Context handoff on model switch. When enabled, FreeLLMAPI injects a compact
# system message into the outbound request whenever a session switches from one
# model to another (e.g. after a fallback). Off by default.
# FREELLMAPI_CONTEXT_HANDOFF=on_model_switch
# Comma-separated extra origins allowed to call the API from a browser.
# localhost:5173, 127.0.0.1:5173, [::1]:5173 are allowed by default for the
# Vite dev dashboard. Only set this if you serve the dashboard from a
# different host than the API (e.g. http://my-server.local).
# DASHBOARD_ORIGINS=http://my-server.local,http://192.168.1.50
# --- Advanced / embedding ---------------------------------------------------
# Path to a prebuilt client `dist` directory to serve. Defaults to the bundled
# client build; set this only if you build the dashboard separately.
# CLIENT_DIST=/path/to/client/dist
# Explicit path to the .env file to load. Useful for embedders (e.g. the
# desktop app, where the code runs from inside a bundle). Defaults to ./.env.
# FREEAPI_ENV_PATH=/path/to/.env