- Docs
- Operate
- Configuration
Configuration
Service configuration via environment variables (no config files)
Zever reads all service configuration from environment variables only. There are no config files (zever.yaml, .yml, .json are ignored).
Quick start
Section titled “Quick start”Layers (later wins): defaults < .env < .env.local < process environment.
- defaults:
config.Default()— zero-infra adapters (sqlite, slog, stdhttp, memory caches, etc.) .env: project-committed example + local overrides (gitignored).env.local: machine-local overrides (gitignored, higher priority)- process environment: highest priority, no file I/O
DB_ADAPTER=postgresDB_DSN=postgres://app:secret@db:5432/appDB_MAX_CONNS=20CACHE_ADAPTER=redisCACHE_ADDR=redis:6379AUTH_ADAPTER=jwtAUTH_JWT_SECRET=prod-secret-at-least-32-bytes-longResolve from env
Section titled “Resolve from env”env, err := config.FromEnv() // reads .env, .env.local, process envresolved, err := config.Resolve(env) // typed ConfigOr in one step: config.LoadEnv() (same as FromEnv).
cfg, err := config.LoadEnv()container.New(cfg, app.Providers()...)Map environment variables to keys
Section titled “Map environment variables to keys”Env names carry no prefix: <SERVICE>_<FIELD>, uppercased.
- Default instance:
SERVICE_FIELD(e.g.,DB_ADAPTER=postgres) - Named instance:
SERVICE__NAME__FIELD(e.g.,DB__ANALYTICS__DSN=...)
Matching ignores case and _, so MAX_RETRIES matches MaxRetries. One nesting level splits at the first _: AUTH_JWT_SECRET sets Options.JWT.Secret.
Durations accept "5s" strings in env only; files store time.Duration as integer nanoseconds.
Default adapters (zero-infra)
Section titled “Default adapters (zero-infra)”| Service | Default Adapter |
|---|---|
| db | sqlite |
| cache | memory |
| queue | memory |
| log | slog |
| router | stdhttp |
| … | (see config.Default()) |
Migration from v0.7
Section titled “Migration from v0.7”| v0.7 | v0.8 |
|---|---|
zever.yaml |
.env + wiring.go |
config.Load("") |
config.FromEnv() / config.LoadEnv() |
ServiceConfig.Adapter |
wired in wiring.go via container.Provide |
DB_MAXCONNS |
DB_MAXCONNS (same) |
DB__ANALYTICS__DSN |
DB__ANALYTICS__DSN (same format) |
zever doctor --config |
zever doctor (no flag) |
Legacy file warning
Section titled “Legacy file warning”If zever.yaml/.yml/.json exists in the working directory, config.FromEnv() prints a one-line warning:
config: zever.yaml found in working directory: ignored; see migration guide in config/README.mdThe file is ignored entirely — no values are read from it.
Generated env template
Section titled “Generated env template”zever new and zever add generate .env.example with every env key, default value, and comment. This is the authoritative source for what env vars each service accepts.
Redact config before printing
Section titled “Redact config before printing”Raw option maps may hold secrets. (*Config).RedactedServices (built on Redact) is the sole display path: error text names services and fields only, and zever config show prints one <service> adapter=<x> header per service plus its masked options.
for name, sc := range cfg.RedactedServices() { fmt.Println(name, sc.Adapter, sc.Options)}Know the defaults
Section titled “Know the defaults”Defaults pick the zero-infra adapter per service (db sqlite, cache/queue/session memory, storage local, log slog, observability stdout, payment/billing stub, secrets env with prefix ZEVER). Two need keys: ai defaults to anthropic and requires an API key, and mailer defaults to log with a dummy localhost:25. The full table is the adapters matrix.
Troubleshooting
Section titled “Troubleshooting”Unknown field error
A pre-rename flat spelling. Rename it to snake_case (e.g., maxconns → max_conns).
Unknown field under a wired service prefix
config.Resolve fails with a did-you-mean hint. Check the service’s options struct.
DB_MAXCONNS=abc returns InvalidOptionsError
A resolved field failed to parse. Set an integer. Unset variables are ignored, bad values are not.
AUTH_TOKEN does nothing
Env is best-effort: AUTH is known but the remainder matches no field. Set AUTH_JWT_SECRET.