In configuration.nix can I read a value from a file?

Hello Nix!

I’m planning to use the CodiMD service and unfortunately there is no way to set the database password using a passwordFile option like proposed in the Provide options for storing secrets outside the Nix store issue.

Is it possible to use some code in my configuration.nix that will be able to read a file during a nixos-rebuild... and store its content as an environment variable? Something like:

environment.variables.CMD_DB_URL = `cat /etc/secret/codimd-dburl.txt`

That way CodiMD will use that environment variable and AFAIU it will not be saved in the nix store.

Any hint please?

Thanks! Gio’

1 Like

Not sure about arbitrary directories but you can read a file in the current directory (which is /etc/nixos) using builtins.readFile. For instance here is how I add custom TLS certificates:

security.pki.certificates = [ (builtins.readFile ./ca-bundle.crt) ];
5 Likes

No. There are very few options you can set in configuration.nix that don’t end up stored in the Nix store. That’s how it can do atomic upgrades and rollbacks; because as much as humanly possible is in the nix store, and referred to by a top level derivation that symlinks to everything.

Setting environment variables for services will store the value in a systemd unit file in the store, or in a script file in the store, or something. Most NixOS services have an extraConfig option or something, which allows you to specify custom text for the config file, allowing you to specify a path of your choice rather than a nix store path. Looks like CodiMD doesn’t have such an option, so you probably need to do some hacking to do what you want.

1 Like

Hi Alex,

Alex Vorobiev via NixOS Discourse nixos1@discoursemail.com writes:

Not sure about arbitrary directories but you can read a file in the current directory (which is /etc/nixos) using builtins.readFile. For instance here is how I add custom TLS certificates:

security.pki.certificates = [ (builtins.readFile ./ca-bundle.crt) ];

I tested this way

environment.variables.TEST_ENVIRONMENT = [ (builtins.readFile ./secrets/env_test) ];

and it works

Thanks! Gio’

[…]

Hello Will,

Will Fancher via NixOS Discourse nixos1@discoursemail.com writes:

[…]

No. There are very few options you can set in configuration.nix that
don’t end up stored in the Nix store. That’s how it can do atomic
upgrades and rollbacks; because as much as humanly possible is in the
nix store, and referred to by a top level derivation that symlinks to
everything.

I knew this, thanks

Setting environment variables for services will store

[…]

Thank you, I can’t find where I read that declared environment variables
are not stored (in the store)… and it did not make much sense to me

The environment variable I used for testing is defined for the root env
and stored in a couple of files in the store, e.g.:

./7xfn56j0ylgjmy3mr1v5v4bm5f924n33-set-environment
./jai29gm730rznznq2di5ghlgadz755lx-set-environment.drv

Most NixOS services have an extraConfig option or something, which
allows you to specify custom text for the config file, allowing you to
specify a path of your choice rather than a nix store path. Looks like
CodiMD doesn’t have such an option,

Yes, CodiMD does not
Provide options for storing secrets outside the Nix store;
it’s a pity issues like this one are still (since mid 2017) not
addressed before adding a service to Nixos

so you probably need to do some hacking to do what you want.

I’m not able to find a workaround or other hack to this issue, I’m going
to file an issue.

Thanks! Gio’

This is just a guess, but maybe something like this is possible?

systemd.services.codimd.serviceConfig.EnvironmentFile = "/etc/secrets/codimd.env";
1 Like