fabrica

hanna/fabrica

4122 bytes

Configuration

fabrica reads a single TOML file, layered over built-in defaults and overridable by the environment. A fully-commented starting point ships as fabrica.example.toml; copy it, keep only the keys you change, and validate with fabrica config check.

Resolution order

Sources are merged in the following order; a later source overrides an earlier one key-by-key:

  1. Built-in defaults (every key has one — a bare config is valid).
  2. /etc/fabrica/fabrica.toml
  3. $XDG_CONFIG_HOME/fabrica/fabrica.toml (falls back to $HOME/.config/fabrica/fabrica.toml)
  4. --config <path> passed on the command line
  5. FABRICA__* environment variables

Missing files are skipped silently, so the same binary serves a first-run machine and a fully-configured one.

Environment overrides

Environment variables are prefixed FABRICA__ and nest with double underscores; single underscores inside a key are preserved:

FABRICA__SERVER__PORT=8080              # -> server.port
FABRICA__INSTANCE__DEFAULT_BRANCH=trunk # -> instance.default_branch
FABRICA__LOG__LEVEL=debug               # -> log.level

Secret files (*_file)

Any key ending in _file reads its value from that file and takes precedence over its inline sibling. This keeps secrets out of the config file for agenix / systemd-creds / Docker secrets:

Inline key File key Contents
auth.secret auth.secret_file HS256 session-signing key
mail.password mail.password_file SMTP password

A single trailing newline is trimmed from the file. Secrets are never logged, never appear in error messages, and render as <redacted> in fabrica config show.

Validation

Validation is strict and fails fast with actionable messages:

Some conditions are warnings — printed to stderr but non-fatal:

Sections

Each section maps one-to-one to a [table] in the TOML file. See fabrica.example.toml for the default value and a comment on every key.

Section Purpose
[instance] Identity, canonical URL, default branch, anonymous access.
[server] HTTP bind address/port, proxy trust, body-size and drain limits.
[ssh] SSH bind address/port, host key path, advertised clone endpoint.
[storage] Data and repository directories on disk.
[database] Connection URL (sqlite:/postgres:) and pool size.
[auth] Session/token lifetimes, cookie settings, Argon2id cost, signing key.
[mail] Backend (smtp/stdout/none), sender, SMTP endpoint and encryption.
[ui] Theme, asset/theme directories, diff/highlight limits.
[git] git binary path and pack-transport limits.
[log] Level and format (pretty/json).

Commands

Both honour the global --config <path> flag.