Is there a way to work with files outside /nix in nixops?

I’m using nixops and want to create certain directories on VM build. For example, I need to create /var/mail and /var/spool/mail for mail, and not-world-readable directories to store keys (I don’t want to use deployment.keys since I don’t want my server to go down after a restart).

Is there a way to build these directories in nixops?

Hi, sure, you just set systemd.tmpfiles.rules. For the syntax, you can refer to man tmpfiles.d.

Thanks, though as I understand it, systemd.tmpfiles creates temporary files, which may be automatically removed, and emails should preferably never be removed without manual intervention.

Temporary, permanent, whatever you want. systemd uses it itself to create the persistent log storage as an example. You can take a look in /etc/tmpfiles.d/systemd.conf.

1 Like

You need to set them up when switching to the configuration.
I just add a service similar to this when I have to do something like this. As you can see I also generate a keyfile and populate it with random data.

  systemd.services.roundcube-install = {
    serviceConfig.Type = "oneshot";
    wantedBy = [ "multi-user.target" ];
    script = ''
      mkdir -p /var/lib/roundcube/temp /var/lib/roundcube/logs
      chown -Rc roundcube:root /var/lib/roundcube
      chmod -c 700 /var/lib/roundcube
      if [ ! -s "/var/lib/roundcube/des_key" ]; then
        ${pkgs.coreutils}/bin/dd if=/dev/urandom bs=32 count=1 2>/dev/null | ${pkgs.coreutils}/bin/base64 > "/var/lib/roundcube/des_key"
        chown -c roundcube:root "/var/lib/roundcube/des_key"
        chmod -c 400 "/var/lib/roundcube/des_key"
      fi
      if [ -s "/var/lib/roundcube/roundcube.sqlite" ]; then
        # Just go ahead and remove the sessions on a boot
        ${pkgs.sqlite}/bin/sqlite3 "/var/lib/roundcube/roundcube.sqlite" "DELETE FROM session;"
      fi
    '';
  };

The activation scripts will take care of setting up tmpfiles as well, so they will be created on activation using nixops. But it really depends on what you’re trying to do. If all that needs to happen is creating directories and setting permissions, then systemd.tmpfiles.rules is the most declarative thing to do.

1 Like

I don’t really think deployment.keys is appropriate for creating directories for a service, but deployment.keys doesn’t have to be exclusively in /run. You can set path to any path you’d like to use.

It sure is. Anything for which StateDirectory, RunDirectory and friends aren’t sufficient, systemd recommends using systemd-tmpfiles

The way I read @ryantm’s message, he’s referring to the use of deployment.keys to create directories.

1 Like

Thanks, I edited it to be more clear.