How to declaratively create a file (/symlink) at a particular path

I’m looking to host some files from a NixOS server using static-web-server. I’d like /var/public to be the root, and I’d like it to contain a mixture of:

  • binary files (images/videos) that are part of a nix configuration (downloaded via fetchurl)
  • dynamic files that I can modify via standard non-nix-y ways

I think I know how to create a single derivation which contains a list of symlinks, but this would result in the entire directory being a symlink to the nix store, which would fail when I try to copy a file into it.

I saw this question which suggests using systemd.tmpfiles, and while this seems like it would work to create the directory /var/public, I couldn’t find a way to create specific files with specific contents - i.e. /var/public/foo.png that is a symlink to the nix store.

I get the feeling there must be a simpler way, because this seems like a pretty fundamental operation, and I’ve spent a long time on it and don’t feel like I have an elegant solution.

Thanks :sweat_smile:

That’s still how you do it, see the man pages: tmpfiles.d

You’re looking for the L+, f+ and C+ variants. Yes the syntax is tedious.

2 Likes

Thanks, that worked :grin: I was able to get it working with

systemd.tmpfiles.rules = let
  image = pkgs.fetchurl { /* ... */ };
in [
  "L+ /var/public/foo.png - - - - ${image}"
];
1 Like