at 23.11-beta 4.5 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.dockerRegistry; 7 8 blobCache = if cfg.enableRedisCache 9 then "redis" 10 else "inmemory"; 11 12 registryConfig = { 13 version = "0.1"; 14 log.fields.service = "registry"; 15 storage = { 16 cache.blobdescriptor = blobCache; 17 delete.enabled = cfg.enableDelete; 18 } // (optionalAttrs (cfg.storagePath != null) { filesystem.rootdirectory = cfg.storagePath; }); 19 http = { 20 addr = "${cfg.listenAddress}:${builtins.toString cfg.port}"; 21 headers.X-Content-Type-Options = ["nosniff"]; 22 }; 23 health.storagedriver = { 24 enabled = true; 25 interval = "10s"; 26 threshold = 3; 27 }; 28 }; 29 30 registryConfig.redis = mkIf cfg.enableRedisCache { 31 addr = "${cfg.redisUrl}"; 32 password = "${cfg.redisPassword}"; 33 db = 0; 34 dialtimeout = "10ms"; 35 readtimeout = "10ms"; 36 writetimeout = "10ms"; 37 pool = { 38 maxidle = 16; 39 maxactive = 64; 40 idletimeout = "300s"; 41 }; 42 }; 43 44 configFile = pkgs.writeText "docker-registry-config.yml" (builtins.toJSON (recursiveUpdate registryConfig cfg.extraConfig)); 45 46in { 47 options.services.dockerRegistry = { 48 enable = mkEnableOption (lib.mdDoc "Docker Registry"); 49 50 package = mkOption { 51 type = types.package; 52 description = mdDoc "Which Docker registry package to use."; 53 default = pkgs.docker-distribution; 54 defaultText = literalExpression "pkgs.docker-distribution"; 55 example = literalExpression "pkgs.gitlab-container-registry"; 56 }; 57 58 listenAddress = mkOption { 59 description = lib.mdDoc "Docker registry host or ip to bind to."; 60 default = "127.0.0.1"; 61 type = types.str; 62 }; 63 64 port = mkOption { 65 description = lib.mdDoc "Docker registry port to bind to."; 66 default = 5000; 67 type = types.port; 68 }; 69 70 storagePath = mkOption { 71 type = types.nullOr types.path; 72 default = "/var/lib/docker-registry"; 73 description = lib.mdDoc '' 74 Docker registry storage path for the filesystem storage backend. Set to 75 null to configure another backend via extraConfig. 76 ''; 77 }; 78 79 enableDelete = mkOption { 80 type = types.bool; 81 default = false; 82 description = lib.mdDoc "Enable delete for manifests and blobs."; 83 }; 84 85 enableRedisCache = mkEnableOption (lib.mdDoc "redis as blob cache"); 86 87 redisUrl = mkOption { 88 type = types.str; 89 default = "localhost:6379"; 90 description = lib.mdDoc "Set redis host and port."; 91 }; 92 93 redisPassword = mkOption { 94 type = types.str; 95 default = ""; 96 description = lib.mdDoc "Set redis password."; 97 }; 98 99 extraConfig = mkOption { 100 description = lib.mdDoc '' 101 Docker extra registry configuration via environment variables. 102 ''; 103 default = {}; 104 type = types.attrs; 105 }; 106 107 enableGarbageCollect = mkEnableOption (lib.mdDoc "garbage collect"); 108 109 garbageCollectDates = mkOption { 110 default = "daily"; 111 type = types.str; 112 description = lib.mdDoc '' 113 Specification (in the format described by 114 {manpage}`systemd.time(7)`) of the time at 115 which the garbage collect will occur. 116 ''; 117 }; 118 }; 119 120 config = mkIf cfg.enable { 121 systemd.services.docker-registry = { 122 description = "Docker Container Registry"; 123 wantedBy = [ "multi-user.target" ]; 124 after = [ "network.target" ]; 125 script = '' 126 ${cfg.package}/bin/registry serve ${configFile} 127 ''; 128 129 serviceConfig = { 130 User = "docker-registry"; 131 WorkingDirectory = cfg.storagePath; 132 AmbientCapabilities = mkIf (cfg.port < 1024) "cap_net_bind_service"; 133 }; 134 }; 135 136 systemd.services.docker-registry-garbage-collect = { 137 description = "Run Garbage Collection for docker registry"; 138 139 restartIfChanged = false; 140 unitConfig.X-StopOnRemoval = false; 141 142 serviceConfig.Type = "oneshot"; 143 144 script = '' 145 ${cfg.package}/bin/registry garbage-collect ${configFile} 146 /run/current-system/systemd/bin/systemctl restart docker-registry.service 147 ''; 148 149 startAt = optional cfg.enableGarbageCollect cfg.garbageCollectDates; 150 }; 151 152 users.users.docker-registry = 153 (optionalAttrs (cfg.storagePath != null) { 154 createHome = true; 155 home = cfg.storagePath; 156 }) // { 157 group = "docker-registry"; 158 isSystemUser = true; 159 }; 160 users.groups.docker-registry = {}; 161 }; 162}