Change:
this commit makes my NVIDIA GeForce RTX 3090 no longer visible to ollama: needs to be revisited, or add optional flag to disable hardening (which i don't really need since I dont expose ollama over internet). when running through systemd: when running :
Can you check , and try adding these strings, prefixed with to ? For me on NixOS 24.05 they show and the module currently allows the following device types:
Just upgraded to the unstable module and package and things are still looking fine. The only nvidia related config I have is
, will try later when I get back home. Not sure if related but I'm on nvidia as the newer versions are broken in one way or another (wayland/performance regressions/pytorch issues).
You can also try nuking the DevicePolicy altogether if the suggestions above do not work: = { DeviceAllow = lib.mkForce [ ]; DevicePolicy = lib.mkForce "auto"; };
was the missing piece: +
--------+ |-----------------------------------------+----------------------+----------------------+ +-----------------------------------------+----------------------+----------------------+
thanks for your support!
Feel free to send a PR to add it to the module. Thanks for looking into this!
some additional findings, nvidia device group names are definitely driver version dependent, this is what I get on 555 ( is gone):

Discussion:
- The Invoiceplane module now only accepts the structured `settings` option. `extraConfig` is now removed. <ins> - The `ollama` services replaces its `sandbox` toggle with options to configure a static `user` and `group`. The `writablePaths` option has been removed and the models directory is now always exempt from sandboxing. </ins> - Legacy package `stalwart-mail_0_6` was dropped, please note the [manual upgrade process](https://github.com/stalwartlabs/mail-server/blob/main/UPGRADING.md) before changing the package to `pkgs.stalwart-mail` in

{ config, lib, pkgs, ... }: let <del> inherit (lib) types mkBefore; </del> <ins> inherit (lib) literalExpression types mkBefore; </ins> cfg = config.services.ollama; ollamaPackage = cfg.package.override { inherit (cfg) acceleration; }; <ins> staticUser = cfg.user != null && cfg.group != null; </ins> in { imports = [ (lib.mkRemovedOptionModule [ "services" "ollama" "listenAddress" ] "Use `services.ollama.host` and `services.ollama.port` instead.") <ins> (lib.mkRemovedOptionModule [ "services" "ollama" "sandbox" ] "Set `services.ollama.user` and `services.ollama.group` instead.") (lib.mkRemovedOptionModule [ "services" "ollama" "writablePaths" ] "The `models` directory is now always writable. To make other directories writable, use `systemd.services.ollama.serviceConfig.ReadWritePaths`." ) </ins> ]; options = { services.ollama = { enable = lib.mkEnableOption "ollama server for local large language models"; package = lib.mkPackageOption pkgs "ollama" { }; <ins> user = lib.mkOption { type = with types; nullOr str; default = null; example = "ollama"; description = '' User account under which to run ollama. Defaults to [`DynamicUser`](https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser=) when set to `null`. The user will automatically be created, if this option is set to a non-null value. ''; }; group = lib.mkOption { type = with types; nullOr str; default = cfg.user; defaultText = literalExpression "config.services.ollama.user"; example = "ollama"; description = '' Group under which to run ollama. Only used when `services.ollama.user` is set. The group will automatically be created, if this option is set to a non-null value. ''; }; </ins> home = lib.mkOption { type = types.str; <del> default = "%S/ollama"; </del> <ins> default = "/var/lib/ollama"; </ins> example = "/home/foo"; description = '' The home directory that the ollama service is started in. <del> See also `services.ollama.writablePaths` and `services.ollama.sandbox`. </del> ''; }; models = lib.mkOption { type = types.str; <del> default = "%S/ollama/models"; </del> <ins> default = "${cfg.home}/models"; defaultText = "${config.services.ollama.home}/models"; </ins> example = "/path/to/ollama/models"; description = '' The directory that the ollama service will read models from and download new models to. <del> See also `services.ollama.writablePaths` and `services.ollama.sandbox` if downloading models or other mutation of the filesystem is required. </del> ''; }; <del> sandbox = lib.mkOption { type = types.bool; default = true; example = false; description = '' Whether to enable systemd's sandboxing capabilities. This sets [`DynamicUser`]( https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser= ), which runs the server as a unique user with read-only access to most of the filesystem. See also `services.ollama.writablePaths`. ''; }; writablePaths = lib.mkOption { type = types.listOf types.str; default = [ ]; example = [ "/home/foo" "/mnt/foo" ]; description = '' Paths that the server should have write access to. This sets [`ReadWritePaths`]( https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#ReadWritePaths= ), which allows specified paths to be written to through the default sandboxing. See also `services.ollama.sandbox`. ''; }; </del> host = lib.mkOption { type = types.str; default = "127.0.0.1"; <del> example = "0.0.0.0"; </del> <ins> example = "[::]"; </ins> description = '' The host address which the ollama server HTTP interface listens to. '';

}; config = lib.mkIf cfg.enable { <ins> users = lib.mkIf staticUser  { users.${cfg.user} = { inherit (cfg) home; isSystemUser = true; group = cfg.group; }; groups.${cfg.group} = {}; }; </ins> systemd.services.ollama = { description = "Server for local large language models"; wantedBy = [ "multi-user.target" ];

OLLAMA_HOST = "${cfg.host}:${toString cfg.port}"; HSA_OVERRIDE_GFX_VERSION = lib.mkIf (cfg.rocmOverrideGfx != null) cfg.rocmOverrideGfx; }; <del> serviceConfig = { </del> <ins> serviceConfig = lib.optionalAttrs staticUser { User = cfg.user; Group = cfg.group; } // { DynamicUser = true; </ins> ExecStart = "${lib.getExe ollamaPackage} serve"; WorkingDirectory = cfg.home; StateDirectory = [ "ollama" ]; <del> DynamicUser = cfg.sandbox; ReadWritePaths = cfg.writablePaths; </del> <ins> ReadWritePaths = [ cfg.home cfg.models ]; CapabilityBoundingSet = [ "" ]; DeviceAllow = [ # CUDA # https://docs.nvidia.com/dgx/pdf/dgx-os-5-user-guide.pdf "char-nvidiactl" "char-nvidia-caps" "char-nvidia-uvm" # ROCm "char-drm" "char-kfd" ]; DevicePolicy = "closed"; LockPersonality = true; MemoryDenyWriteExecute = true; NoNewPrivileges = true; PrivateDevices = false; # hides acceleration devices PrivateTmp = true; PrivateUsers = true; ProcSubset = "all"; # /proc/meminfo ProtectClock = true; ProtectControlGroups = true; ProtectHome = true; ProtectHostname = true; ProtectKernelLogs = true; ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; ProtectSystem = "strict"; RemoveIPC = true; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ]; SupplementaryGroups = [ "render" ]; # for rocm to access /dev/dri/renderD* devices SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service @resources" "~@privileged" ]; UMask = "0077"; </ins> }; postStart = mkBefore '' set -x