at 24.11-pre 4.5 kB view raw
1{ config, lib, pkgs, ... }: 2let 3 inherit (lib) types; 4 5 cfg = config.services.ollama; 6 ollamaPackage = cfg.package.override { 7 inherit (cfg) acceleration; 8 linuxPackages = config.boot.kernelPackages // { 9 nvidia_x11 = config.hardware.nvidia.package; 10 }; 11 }; 12in 13{ 14 options = { 15 services.ollama = { 16 enable = lib.mkEnableOption "ollama server for local large language models"; 17 package = lib.mkPackageOption pkgs "ollama" { }; 18 home = lib.mkOption { 19 type = types.str; 20 default = "%S/ollama"; 21 example = "/home/foo"; 22 description = '' 23 The home directory that the ollama service is started in. 24 25 See also `services.ollama.writablePaths` and `services.ollama.sandbox`. 26 ''; 27 }; 28 models = lib.mkOption { 29 type = types.str; 30 default = "%S/ollama/models"; 31 example = "/path/to/ollama/models"; 32 description = '' 33 The directory that the ollama service will read models from and download new models to. 34 35 See also `services.ollama.writablePaths` and `services.ollama.sandbox` 36 if downloading models or other mutation of the filesystem is required. 37 ''; 38 }; 39 sandbox = lib.mkOption { 40 type = types.bool; 41 default = true; 42 example = false; 43 description = '' 44 Whether to enable systemd's sandboxing capabilities. 45 46 This sets [`DynamicUser`]( 47 https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser= 48 ), which runs the server as a unique user with read-only access to most of the filesystem. 49 50 See also `services.ollama.writablePaths`. 51 ''; 52 }; 53 writablePaths = lib.mkOption { 54 type = types.listOf types.str; 55 default = [ ]; 56 example = [ "/home/foo" "/mnt/foo" ]; 57 description = '' 58 Paths that the server should have write access to. 59 60 This sets [`ReadWritePaths`]( 61 https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#ReadWritePaths= 62 ), which allows specified paths to be written to through the default sandboxing. 63 64 See also `services.ollama.sandbox`. 65 ''; 66 }; 67 listenAddress = lib.mkOption { 68 type = types.str; 69 default = "127.0.0.1:11434"; 70 example = "0.0.0.0:11111"; 71 description = '' 72 The address which the ollama server HTTP interface binds and listens to. 73 ''; 74 }; 75 acceleration = lib.mkOption { 76 type = types.nullOr (types.enum [ false "rocm" "cuda" ]); 77 default = null; 78 example = "rocm"; 79 description = '' 80 What interface to use for hardware acceleration. 81 82 - `null`: default behavior 83 if `nixpkgs.config.rocmSupport` is enabled, uses `"rocm"` 84 if `nixpkgs.config.cudaSupport` is enabled, uses `"cuda"` 85 otherwise defaults to `false` 86 - `false`: disable GPU, only use CPU 87 - `"rocm"`: supported by most modern AMD GPUs 88 - `"cuda"`: supported by most modern NVIDIA GPUs 89 ''; 90 }; 91 environmentVariables = lib.mkOption { 92 type = types.attrsOf types.str; 93 default = { }; 94 example = { 95 OLLAMA_LLM_LIBRARY = "cpu"; 96 HIP_VISIBLE_DEVICES = "0,1"; 97 }; 98 description = '' 99 Set arbitrary environment variables for the ollama service. 100 101 Be aware that these are only seen by the ollama server (systemd service), 102 not normal invocations like `ollama run`. 103 Since `ollama run` is mostly a shell around the ollama server, this is usually sufficient. 104 ''; 105 }; 106 }; 107 }; 108 109 config = lib.mkIf cfg.enable { 110 systemd.services.ollama = { 111 description = "Server for local large language models"; 112 wantedBy = [ "multi-user.target" ]; 113 after = [ "network.target" ]; 114 environment = cfg.environmentVariables // { 115 HOME = cfg.home; 116 OLLAMA_MODELS = cfg.models; 117 OLLAMA_HOST = cfg.listenAddress; 118 }; 119 serviceConfig = { 120 ExecStart = "${lib.getExe ollamaPackage} serve"; 121 WorkingDirectory = cfg.home; 122 StateDirectory = [ "ollama" ]; 123 DynamicUser = cfg.sandbox; 124 ReadWritePaths = cfg.writablePaths; 125 }; 126 }; 127 128 environment.systemPackages = [ ollamaPackage ]; 129 }; 130 131 meta.maintainers = with lib.maintainers; [ abysssol onny ]; 132}