Where to put a packages variable data?

I’ve been trying to get neo4j setup but I can’t figure out where to put directories it needs to write to. The current package in nixpkgs copies all it’s directories into /nix/store via cp -R * $out/share/neo4j, however, this includes logs/, run/, and data/ all of which neo4j needs to write to, preventing neo4j from starting. I can fix this by moving these directories to a writable location but I cannot figure out where they should go.

In the meantime, I have hardcoded my home directory into the installPhase to put them in $HOME/.local/share/neo4j. This is done by editing the conf file, which is also in $out so it can only be written to when I don’t have access to $HOME. There may be a way to pass it a path with ‘~’ in it that neo4j expands itself after installation but given the lengths nix goes to prevent the installation process from using $HOME I assume that is not a proper solution.

The /tmp directory is not acceptable as data/ needs to be persistent. Also, ideally, the directory should be independent of the exact build so data is available across updates. Somewhere in /var like /var/neo4j would work but nixbld does not have permission to write there. Doesn’t seem like an uncommon scenerio but I’m failing to find the correct way to handle it.

3 Likes

The usual recipe is to create a directory under /var/lib, so /var/lib/neo4j I would say, owned by the user that will be the owner of the neo4j service.

The creation of the directory and that of the structure underneath is deferred to the installation time via system.activationScripts but more frequently by assigning a setup script to the associated service config preStart entry, this is done by the configuration module.

I was planning on using neo4j for basinix, but decided that I couldn’t take full advantage of a graph database until much later anyway… so i dropped it. But if you’re interested my work can be found: neo4j: 3.5.14 -> 4.1.1 by jonringer · Pull Request #98443 · NixOS/nixpkgs · GitHub

I have been using flakes to keep my projects contained. Rather than installing neo4j globally I use it as a dependency within another flake. It is not obvious to me that I would be able to use either of those methods in this scenerio. I would assume both need to be added to configuration.nix or possibly within home-manager if that is used.

Based of @jonringer’s link I tried modifying my flake to work with systemd but I don’t expect a flake would be able to create the neo4j user without nixos-rebuild, which shouldn’t know about it. (I’m also pretty confident I didn’t set up the service correct but gave up when I realized it likely wouldn’t be possible.)

In this case, since it is not installed system-wide, maybe the best place for data is within the users home? Or am I stuck making this a service and adding enabling it in my configuration.nix?

Yes, indeed, in such case it’s better to keep it under /home/, as of now for other services i build the “var” skeleton during normal package creation together with a script that can can prepare a such structure in the development environment, then i create the concrete structure at nix develop time and then I use gnu make or just (a new development automation tool written in rust) to start the local service. If you plan to use systemd user services I think you will want to run them as your own user and maybe to put such structure inside /home/david/.local.

Lately, after looking at the talk that @sander gave at the last conference I intend to use nix-processmgmt to replace those scripts with proper service instances. From a generic description it can generate systemd, supervisord and other (user) services or even generate and start for you a bunch of docker images (a-la docker-compose), for maximum flexibility. It can be further extended probably to build launchd services on macOS. I’ve not grasped it completely yet to show you something working but I think it really nice. It lacks a flake definition but It’s not a big deal.