Host permissions for container bindmount

I’m trying to move some of my services to nixos containers. Working on nextcloud, I’m not sure how to ensure the permissions of my nextcloud’s data directory stored on the host is correct to allow the container’s nextcloud user to read/write to the directory.

The goal is to run containers using the ephemeral setting and storing the persistent data in /data/${service}. The service in the container should be run by an unprivileged user, outside of the container the user should only be able to read and write to that services data directory.

Modifying the example from the wiki’s nixos container page, I have something like this:

{ pkgs, ... }:

{
  networking.nat = {
    enable = true;
    internalInterfaces = [ "ve-nextcloud" ];
    externalInterface = "eth0";
  };
  services.nginx.virtualHosts."nextcloud.test".locations."/".proxyPass =
    "http://10.0.2.17:80";

  containers.nextcloud = {
    autoStart = true;
    ephemeral = true;
    privateNetwork = true;
    hostAddress = "10.0.2.16";
    localAddress = "10.0.2.17";

    bindMounts = {
      "/var/lib/nextcloud" = {
        hostPath = "/data/nextcloud";
        isReadOnly = false;
      };
    };

    config = { config, pkgs, ... }: {
      systemd.tmpfiles.rules =
        [ "d /var/lib/nextcloud 700 nextcloud nextcloud -" ];

      services.nextcloud = {
        enable = true;
        package = pkgs.nextcloud27;
        hostName = "nextcloud.test";
        home = "/var/lib/nextcloud";
        config.adminpassFile = "${pkgs.writeText "adminpass" "test123"}";
        enableBrokenCiphersForSSE = false;
      };

      system.stateVersion = "22.05";

      networking.firewall = {
        enable = true;
        allowedTCPPorts = [ 80 ];
      };

      # Manually configure nameserver. Using resolved inside the container seems to fail
      # currently
      environment.etc."resolv.conf".text = "nameserver 9.9.9.9";
    };
  };
}

From my understanding, a user inside the container has the same UID in the container as on the host. In my case the container user nextcloud has UID 996, which is the same UID already in use by dhcpcd on the vm I was testing this on. I can get everything working by giving dhcpcd ownership of the /data/nextcloud directory. But this wrongly gives dhcpcd access to nextcloud data and vice versa, it’s possible that multiple containers will create users with the same UID, and I don’t know ahead of time what UID the container’s user will get in order to set the permissions on the host beforehand (and I’m not sure if it’s constant between restarts).

I know I can explicitly pass the uid to the user. So if I manually create the nextcloud user on the host and container I can provide that. This potentially fixes all the above problems but it requires me keeping track of UID for each service so I don’t reuse numbers and that I am in charge of making sure the UID isn’t already in use.

Is there a better way to give a container user access to a bindmount? Can I ensure there’s an analogous user on both host and container with the same UID without having to manually set the UID for each service I run? Can I get a user’s ID from nix? If so I could make a user on the host without specifying the UID, get the ID, then create the same user inside the container specifying that UID.