Table of contents
Part of nurago, a collection of independent Go packages for backend services.
import "github.com/tecnickcom/nurago/pkg/config"
Loads configuration from defaults, a file, the environment and optionally a remote source, in a fixed order, then validates the result. Built on Viper.
An application implements two methods:
SetDefaults(v Viper) // register application defaults
Validate() error // enforce final constraints
The load order
Later steps override earlier ones:
- Built-in defaults from this package (log and shutdown settings), plus your
SetDefaults. - A local config file,
config.jsonby default, searched in an explicitconfigDirfirst, then./,$HOME/.<cmdName>/,/etc/<cmdName>/. - Environment overrides.
- An optional remote source through
WithRemoteLoader. Validate.
Fixing the order is the point. The common alternative, each service resolving precedence in its own main, produces subtly different behaviour per service, and the difference is only discovered when an environment variable that works in one service is ignored in another.
The search path covers the three deployment shapes without configuration: a repository-local file during development, a per-user file, and /etc for a system install.
Environment overrides make containers work
Every setting is overridable from the environment, and the envvar provider allows a file-less configuration entirely from environment data.
That is what makes the same binary work in a container without a config file baked in or mounted. It also keeps secrets out of files, since a database password or an API key arrives as an environment variable from the orchestrator’s secret store rather than sitting on disk.
Validation runs last, and should be strict
Validate runs after every source has been merged, so it sees the effective configuration rather than any one layer.
This is the cheapest place in a service to catch a mistake. A missing database URL, a port of zero, a timeout that is negative: all of them fail at startup with a specific message, rather than at the first request that needs them. In a rolling deployment, a process that exits at startup fails the rollout and leaves the previous version serving; one that starts and fails later takes traffic first.
Worth validating relationships, not only presence. A shutdown timeout shorter than the request timeout is individually valid and jointly wrong, and Validate sees both.
validator covers struct-tag validation where the rules are per-field.
Remote sources
WithRemoteLoader is a pluggable hook rather than a built-in integration with any particular system, so Consul, etcd, or an internal service can supply configuration without the package depending on any of them.
It sits above the environment in precedence and below validation, so a remote value is still checked.
Lineage
The model follows Software Configuration, written by this library’s author in 2014, which is where the layered precedence and the search-path convention come from.
Dependencies
Reaches github.com/spf13/viper.
Links
- Reference documentation
- Source code
- Field-level validation: validator
- Service wiring: bootstrap
- Getting started: /docs/getting-started/
- All nurago packages