Configuration files and precedence
Deze inhoud is nog niet beschikbaar in uw taal.
This reference reflects Onetime Secret v0.26.19 (e98a88c9).
The files
Section titled “The files”Four subjects have their own configuration file. Each one is resolved separately, and each one has a shipped defaults file beside it.
| Subject | Shipped defaults | Deployment file | Loader |
|---|---|---|---|
| Main application | etc/defaults/config.defaults.yaml |
etc/config.yaml |
lib/onetime/config.rb |
| Authentication | etc/defaults/auth.defaults.yaml |
etc/auth.yaml |
lib/onetime/auth_config.rb |
| Logging | etc/defaults/logging.defaults.yaml |
etc/logging.yaml |
lib/onetime/initializers/setup_loggers.rb |
| Billing | none shipped | etc/billing.yaml |
lib/onetime/billing_config.rb |
The shipped defaults files are part of the application. Edit the deployment
file next to them instead, and leave etc/defaults/ untouched, so an upgrade
can replace the defaults without discarding your settings.
Billing ships an example rather than a defaults file. If etc/billing.yaml
does not exist, the billing configuration is empty and billing is off.
How a file is found
Section titled “How a file is found”For each subject, path resolution runs in this order:
- When
RACK_ENV=test,spec/<subject>.test.yaml, thenapps/**/spec/<subject>.test.yaml. etc/<subject>.yaml.
The shipped defaults file is resolved separately and only at
etc/defaults/<subject>.defaults.yaml.
If no main configuration file is found at all, the search falls back to fixed
directories: /etc/onetime, ./etc and ./etc/defaults when the application
runs as a service, and ~/.onetime first when it runs as a command-line
utility.
There is no environment variable that selects the configuration file path at
this release. A search for ONETIME_CONFIG across the application returns no
matches, so the paths above are the whole mechanism.
Passing an explicit path to the main loader is the one way to bypass the defaults layer. When a path is given, the shipped defaults file is not read and the single file is used as it stands.
How values combine
Section titled “How values combine”Three layers resolve a key, in this order:
- The shipped defaults file is the base.
- The deployment file is deep-merged on top, so a value you set wins over the shipped one. Nils are not preserved at this step: an explicit nil in the deployment file means nil, and does not fall back to the shipped value.
- In-code defaults are then merged underneath, with nils preserved. A key that resolved to nil through the first two steps takes the in-code default.
Deep merge means per-key, at every depth. Setting one key inside a section leaves its siblings at their shipped values; it does not replace the section.
Two consequences of step 3 are worth stating outright:
- An empty string is a value. In Ruby
""is truthy, so a key set to an empty string replaces the in-code default rather than falling through to it. - A key you want to clear back to the in-code default has to be nil, not empty.
The authentication and logging files layer the same way through the same merge. The authentication file is stricter about YAML types: its loader permits no extra classes, so an unquoted date that the main file would accept raises an error there. A failure to load the authentication file stops the boot.
How environment variables reach a key
Section titled “How environment variables reach a key”Environment variables are not a configuration layer. They take effect only through ERB inside the YAML files: the loader renders each file with ERB and then parses the result. A key whose value in the shipped defaults file is a literal cannot be set from the environment at all.
That is why the key records say which variables reach each key, and why some
keys list none. The three shapes you will see in the shipped files are a plain
read (<%= ENV['HOST'] %>), a read with a literal fallback
(<%= ENV['HOST'] || 'localhost:3000' %>) and a boolean comparison
(<%= ENV['SSL'] == 'true' %>). A few values are computed from several reads
and are reported as determined at run time, with the expression shown.
Because the environment is read during ERB rendering, an environment value behaves as though it were written in the file it appears in. The layering above then applies to the rendered result.
Deprecated keys and variables
Section titled “Deprecated keys and variables”When the application finds a removed or relocated configuration key, or its
environment variable, at boot, compatibility.deprecated_config_mode decides
what happens:
| Value | Behaviour |
|---|---|
strict |
Raise a configuration error and refuse to start. This is the default. |
warn |
Log a migration message and continue. |
silent |
Ignore it. |
An unrecognized value is treated as strict. Entries the application marks as
warn-severity log under both strict and warn rather than stopping the boot.
So the default posture is that a configuration file left over from an older release stops the boot with an error naming the key, instead of starting with the setting quietly ignored.
Which page owns which keys
Section titled “Which page owns which keys”Every key in the shipped defaults files has one owning reference page.
| Page | Keys it owns |
|---|---|
| Site and interface | site.* except secret options and sign-in switches, internationalization.*, diagnostics.* |
| Features and branding | features.*, brand.*, site.secret_options.*, site.authentication.* |
| Datastore and queues | redis.*, jobs.* |
| Email and delivery | emailer.*, email_providers.*, mail.* |
| Auth, logging and billing files | every key in the authentication, logging and billing files |
| This page | development.*, compatibility.*, experimental |
Keys on this page
Section titled “Keys on this page”These keys configure the configuration layer itself and the development-mode
behaviour that depends on it. The values are read from
etc/defaults/config.defaults.yaml at the release named above.
| Key | Value | Environment variables | Since | Source |
|---|---|---|---|---|
development.enabled |
determined at run time: true when RACK_ENV is development or dev |
RACK_ENV |
not annotated | etc/defaults/config.defaults.yaml:2014 |
development.debug |
determined at run time: true when ONETIME_DEBUG is true, 1 or yes |
ONETIME_DEBUG |
not annotated | etc/defaults/config.defaults.yaml:2015 |
development.frontend_host |
http://localhost:5173 |
FRONTEND_HOST |
not annotated | etc/defaults/config.defaults.yaml:2019 |
development.allow_nil_global_secret |
false |
ALLOW_NIL_GLOBAL_SECRET |
v0.24.0 | etc/defaults/config.defaults.yaml:2051 |
development.devbasicauth |
false when unset |
DEV_BASIC_AUTH |
v0.24.6 | etc/defaults/config.defaults.yaml:2066 |
development.devsessionauth |
false when unset |
DEV_SESSION_AUTH |
v0.24.6 | etc/defaults/config.defaults.yaml:2080 |
compatibility.deprecated_config_mode |
strict |
DEPRECATED_CONFIG_MODE |
v0.25.5 | etc/defaults/config.defaults.yaml:2090 |
experimental |
empty mapping | none | v0.26.0 | etc/defaults/config.defaults.yaml:2102 |
development.allow_nil_global_secret takes effect only while
development.enabled is true; the normalization step forces it to false
otherwise. development.devbasicauth and development.devsessionauth register
development-only authentication strategies and are refused in production.
experimental is an empty extension point in the shipped defaults.
Related
Section titled “Related”- Environment variables for every variable the application documents.
- Configuration generator to produce a starting
etc/config.yaml,etc/auth.yamland.envfrom a few choices.