1 # Options for Program Settings {#sec-settings-options}
3 Many programs have configuration files where program-specific settings
4 can be declared. File formats can be separated into two categories:
6 - Nix-representable ones: These can trivially be mapped to a subset of
7 Nix syntax. E.g. JSON is an example, since its values like
8 `{"foo":{"bar":10}}` can be mapped directly to Nix:
9 `{ foo = { bar = 10; }; }`. Other examples are INI, YAML and TOML.
10 The following section explains the convention for these settings.
12 - Non-nix-representable ones: These can't be trivially mapped to a
13 subset of Nix syntax. Most generic programming languages are in this
14 group, e.g. bash, since the statement `if true; then echo hi; fi`
15 doesn't have a trivial representation in Nix.
17 Currently there are no fixed conventions for these, but it is common
18 to have a `configFile` option for setting the configuration file
19 path directly. The default value of `configFile` can be an
20 auto-generated file, with convenient options for controlling the
21 contents. For example an option of type `attrsOf str` can be used
22 for representing environment variables which generates a section
23 like `export FOO="foo"`. Often it can also be useful to also include
24 an `extraConfig` option of type `lines` to allow arbitrary text
25 after the autogenerated part of the file.
27 ## Nix-representable Formats (JSON, YAML, TOML, INI, ...) {#sec-settings-nix-representable}
29 By convention, formats like this are handled with a generic `settings`
30 option, representing the full program configuration as a Nix value. The
31 type of this option should represent the format. The most common formats
32 have a predefined type and string generator already declared under
35 `pkgs.formats.javaProperties` { *`comment`* ? `"Generated with Nix"` }
37 : A function taking an attribute set with values
41 : A string to put at the start of the
42 file in a comment. It can have multiple
45 It returns the `type`: `attrsOf str` and a function
46 `generate` to build a Java `.properties` file, taking
47 care of the correct escaping, etc.
49 `pkgs.formats.hocon` { *`generator`* ? `<derivation>`, *`validator`* ? `<derivation>`, *`doCheck`* ? true }
51 : A function taking an attribute set with values
55 : A derivation used for converting the JSON output
56 from the nix settings into HOCON. This might be
57 useful if your HOCON variant is slightly different
58 from the java-based one, or for testing purposes.
62 : A derivation used for verifying that the HOCON
63 output is correct and parsable. This might be
64 useful if your HOCON variant is slightly different
65 from the java-based one, or for testing purposes.
69 : Whether to enable/disable the validator check.
71 It returns an attrset with a `type`, `generate` function,
72 and a `lib` attset, as specified [below](#pkgs-formats-result).
73 Some of the lib functions will be best understood if you have
74 read the reference specification. You can find this
77 <https://github.com/lightbend/config/blob/main/HOCON.md>
79 Inside of `lib`, you will find these functions
83 : This is used together with a specially named
84 attribute `includes`, to include other HOCON
85 sources into the document.
87 The function has a shorthand variant where it
88 is up to the HOCON parser to figure out what type
89 of include is being used. The include will default
90 to being non-required. If you want to be more
91 explicit about the details of the include, you can
92 provide an attrset with following arguments
96 : Whether the parser should fail upon failure
97 to include the document
101 : Type of the source of the included document.
102 Valid values are `file`, `url` and `classpath`.
103 See upstream documentation for the semantics
108 : The URI/path/classpath pointing to the source of
109 the document to be included.
115 format = pkgs.formats.hocon { };
116 hocon_file = pkgs.writeText "to_include.hocon" ''
120 some.nested.hocon.attrset = {
122 (format.lib.mkInclude hocon_file)
123 (format.lib.mkInclude "https://example.com/to_include.hocon")
124 (format.lib.mkInclude {
127 value = include_file;
137 : This is used to invoke the `+=` operator.
138 This can be useful if you need to add something
139 to a list that is included from outside of nix.
140 See upstream documentation for the semantics
141 behind the `+=` operation.
147 format = pkgs.formats.hocon { };
148 hocon_file = pkgs.writeText "to_include.hocon" ''
154 (format.lib.mkInclude hocon_file)
158 a = format.lib.mkAppend 3;
159 b = format.lib.mkAppend (format.lib.mkSubstitution "c");
165 : This is used to make HOCON substitutions.
166 Similarly to `mkInclude`, this function has
167 a shorthand variant where you just give it
168 the string with the substitution value.
169 The substitution is not optional by default.
170 Alternatively, you can provide an attrset
175 : Whether the parser should fail upon
176 failure to fetch the substitution value.
180 : The name of the variable to use for
183 See upstream documentation for semantics
184 behind the substitution functionality.
190 format = pkgs.formats.hocon { };
193 b = format.lib.mkSubstitution "a";
194 c = format.lib.mkSubstition "SOME_ENVVAR";
195 d = format.lib.mkSubstition {
196 value = "SOME_OPTIONAL_ENVVAR";
202 `Implementation notes:`
204 - classpath includes are not implemented in pyhocon,
205 which is used for validating the HOCON output. This
206 means that if you are using classpath includes,
207 you will want to either use an alternative validator
208 or set `doCheck = false` in the format options.
210 `pkgs.formats.libconfig` { *`generator`* ? `<derivation>`, *`validator`* ? `<derivation>` }
212 : A function taking an attribute set with values
216 : A derivation used for converting the JSON output
217 from the nix settings into libconfig. This might be
218 useful if your libconfig variant is slightly different
219 from the original one, or for testing purposes.
223 : A derivation used for verifying that the libconfig
224 output is correct and parsable. This might be
225 useful if your libconfig variant is slightly different
226 from the original one, or for testing purposes.
228 It returns an attrset with a `type`, `generate` function,
229 and a `lib` attset, as specified [below](#pkgs-formats-result).
230 Some of the lib functions will be best understood if you have
231 read the reference specification. You can find this
234 <https://hyperrealm.github.io/libconfig/libconfig_manual.html#Configuration-Files>
236 Inside of `lib`, you will find these functions
238 `mkHex`, `mkOctal`, `mkFloat`
240 : Use these to specify numbers in other formats.
246 format = pkgs.formats.libconfig { };
248 myHexValue = format.lib.mkHex "0x1FC3";
249 myOctalValue = format.lib.mkOctal "0027";
250 myFloatValue = format.lib.mkFloat "1.2E-3";
256 : Use these to differentiate between whether
257 a nix list should be considered as a libconfig
258 array or a libconfig list. See the upstream
259 documentation for the semantics behind these types.
265 format = pkgs.formats.libconfig { };
267 myList = format.lib.mkList [ "foo" 1 true ];
268 myArray = format.lib.mkArray [ 1 2 3 ];
272 `Implementation notes:`
274 - Since libconfig does not allow setting names to start with an underscore,
275 this is used as a prefix for both special types and include directives.
277 - The difference between 32bit and 64bit values became optional in libconfig
278 1.5, so we assume 64bit values for all numbers.
280 `pkgs.formats.json` { }
282 : A function taking an empty attribute set (for future extensibility)
283 and returning a set with JSON-specific attributes `type` and
284 `generate` as specified [below](#pkgs-formats-result).
286 `pkgs.formats.yaml` { }
288 : A function taking an empty attribute set (for future extensibility)
289 and returning a set with YAML-specific attributes `type` and
290 `generate` as specified [below](#pkgs-formats-result).
292 `pkgs.formats.ini` { *`listsAsDuplicateKeys`* ? false, *`listToValue`* ? null, \.\.\. }
294 : A function taking an attribute set with values
296 `listsAsDuplicateKeys`
298 : A boolean for controlling whether list values can be used to
299 represent duplicate INI keys
303 : A function for turning a list of values into a single value.
305 It returns a set with INI-specific attributes `type` and `generate`
306 as specified [below](#pkgs-formats-result).
307 The type of the input is an *attrset* of sections; key-value pairs where
308 the key is the section name and the value is the corresponding content
309 which is also an *attrset* of key-value pairs for the actual key-value
310 mappings of the INI format.
311 The values of the INI atoms are subject to the above parameters (e.g. lists
312 may be transformed into multiple key-value pairs depending on
315 `pkgs.formats.iniWithGlobalSection` { *`listsAsDuplicateKeys`* ? false, *`listToValue`* ? null, \.\.\. }
317 : A function taking an attribute set with values
319 `listsAsDuplicateKeys`
321 : A boolean for controlling whether list values can be used to
322 represent duplicate INI keys
326 : A function for turning a list of values into a single value.
328 It returns a set with INI-specific attributes `type` and `generate`
329 as specified [below](#pkgs-formats-result).
330 The type of the input is an *attrset* of the structure
331 `{ sections = {}; globalSection = {}; }` where *sections* are several
332 sections as with *pkgs.formats.ini* and *globalSection* being just a single
333 attrset of key-value pairs for a single section, the global section which
334 preceedes the section definitions.
336 `pkgs.formats.toml` { }
338 : A function taking an empty attribute set (for future extensibility)
339 and returning a set with TOML-specific attributes `type` and
340 `generate` as specified [below](#pkgs-formats-result).
342 `pkgs.formats.elixirConf { elixir ? pkgs.elixir }`
344 : A function taking an attribute set with values
348 : The Elixir package which will be used to format the generated output
350 It returns a set with Elixir-Config-specific attributes `type`, `lib`, and
351 `generate` as specified [below](#pkgs-formats-result).
353 The `lib` attribute contains functions to be used in settings, for
354 generating special Elixir values:
358 : Outputs the given string as raw Elixir code
360 `mkGetEnv { envVariable, fallback ? null }`
362 : Makes the configuration fetch an environment variable at runtime
366 : Outputs the given string as an Elixir atom, instead of the default
367 Elixir binary string. Note: lowercase atoms still needs to be prefixed
372 : Outputs the given array as an Elixir tuple, instead of the default
377 : Outputs the given attribute set as an Elixir map, instead of the
378 default Elixir keyword list
380 `pkgs.formats.php { finalVariable }` []{#pkgs-formats-php}
382 : A function taking an attribute set with values
386 : The variable that will store generated expression (usually `config`). If set to `null`, generated expression will contain `return`.
388 It returns a set with PHP-Config-specific attributes `type`, `lib`, and
389 `generate` as specified [below](#pkgs-formats-result).
391 The `lib` attribute contains functions to be used in settings, for
392 generating special PHP values:
396 : Outputs the given string as raw PHP code
398 `mkMixedArray list set`
400 : Creates PHP array that contains both indexed and associative values. For example, `lib.mkMixedArray [ "hello" "world" ] { "nix" = "is-great"; }` returns `['hello', 'world', 'nix' => 'is-great']`
402 []{#pkgs-formats-result}
403 These functions all return an attribute set with these values:
407 : A module system type representing a value of the format
411 : Utility functions for convenience, or special interactions with the format.
412 This attribute is optional. It may contain inside a `types` attribute
413 containing types specific to this format.
415 `generate` *`filename jsonValue`*
417 : A function that can render a value of the format to a file. Returns
421 This function puts the value contents in the Nix store. So this
422 should be avoided for secrets.
425 ::: {#ex-settings-nix-representable .example}
426 ### Module with conventional `settings` option
428 The following shows a module for an example program that uses a JSON
429 configuration file. It demonstrates how above values can be used, along
430 with some other related best practices. See the comments for
434 { options, config, lib, pkgs, ... }:
436 cfg = config.services.foo;
437 # Define the settings format used for this program
438 settingsFormat = pkgs.formats.json {};
441 options.services.foo = {
442 enable = lib.mkEnableOption "foo service";
444 settings = lib.mkOption {
445 # Setting this type allows for correct merging behavior
446 type = settingsFormat.type;
449 Configuration for foo, see
450 <link xlink:href="https://example.com/docs/foo"/>
451 for supported settings.
456 config = lib.mkIf cfg.enable {
457 # We can assign some default settings here to make the service work by just
458 # enabling it. We use `mkDefault` for values that can be changed without
460 services.foo.settings = {
461 # Fails at runtime without any value set
462 log_level = lib.mkDefault "WARN";
464 # We assume systemd's `StateDirectory` is used, so we require this value,
465 # therefore no mkDefault
466 data_path = "/var/lib/foo";
468 # Since we use this to create a user we need to know the default value at
470 user = lib.mkDefault "foo";
473 environment.etc."foo.json".source =
474 # The formats generator function takes a filename and the Nix value
475 # representing the format value and produces a filepath with that value
476 # rendered in the format
477 settingsFormat.generate "foo-config.json" cfg.settings;
479 # We know that the `user` attribute exists because we set a default value
480 # for it above, allowing us to use it without worries here
481 users.users.${cfg.settings.user} = { isSystemUser = true; };
489 ### Option declarations for attributes {#sec-settings-attrs-options}
491 Some `settings` attributes may deserve some extra care. They may need a
492 different type, default or merging behavior, or they are essential
493 options that should show their documentation in the manual. This can be
494 done using [](#sec-freeform-modules).
496 We extend above example using freeform modules to declare an option for
497 the port, which will enforce it to be a valid integer and make it show
500 ::: {#ex-settings-typed-attrs .example}
501 ### Declaring a type-checked `settings` attribute
504 settings = lib.mkOption {
505 type = lib.types.submodule {
507 freeformType = settingsFormat.type;
509 # Declare an option for the port such that the type is checked and this option
510 # is shown in the manual.
511 options.port = lib.mkOption {
512 type = lib.types.port;
515 Which port this service should listen on.
522 Configuration for Foo, see
523 <link xlink:href="https://example.com/docs/foo"/>
524 for supported values.