at 25.11-pre 8.8 kB view raw
1{ 2 config, 3 pkgs, 4 lib, 5 ... 6}: 7let 8 cfg = config.services.homepage-dashboard; 9 # Define the settings format used for this program 10 settingsFormat = pkgs.formats.yaml { }; 11in 12{ 13 options = { 14 services.homepage-dashboard = { 15 enable = lib.mkEnableOption "Homepage Dashboard, a highly customizable application dashboard"; 16 17 package = lib.mkPackageOption pkgs "homepage-dashboard" { }; 18 19 openFirewall = lib.mkOption { 20 type = lib.types.bool; 21 default = false; 22 description = "Open ports in the firewall for Homepage."; 23 }; 24 25 listenPort = lib.mkOption { 26 type = lib.types.int; 27 default = 8082; 28 description = "Port for Homepage to bind to."; 29 }; 30 31 allowedHosts = lib.mkOption { 32 type = lib.types.str; 33 default = "localhost:8082,127.0.0.1:8082"; 34 example = "example.com"; 35 description = '' 36 Hosts that homepage-dashboard will be running under. 37 You will want to change this in order to acess homepage from anything other than localhost. 38 see the upsream documentation: 39 40 <https://gethomepage.dev/installation/#homepage_allowed_hosts> 41 ''; 42 }; 43 44 environmentFile = lib.mkOption { 45 type = lib.types.str; 46 description = '' 47 The path to an environment file that contains environment variables to pass 48 to the homepage-dashboard service, for the purpose of passing secrets to 49 the service. 50 51 See the upstream documentation: 52 53 <https://gethomepage.dev/installation/docker/#using-environment-secrets> 54 ''; 55 default = ""; 56 }; 57 58 customCSS = lib.mkOption { 59 type = lib.types.lines; 60 description = '' 61 Custom CSS for styling Homepage. 62 63 See <https://gethomepage.dev/configs/custom-css-js/>. 64 ''; 65 default = ""; 66 }; 67 68 customJS = lib.mkOption { 69 type = lib.types.lines; 70 description = '' 71 Custom Javascript for Homepage. 72 73 See <https://gethomepage.dev/configs/custom-css-js/>. 74 ''; 75 default = ""; 76 }; 77 78 bookmarks = lib.mkOption { 79 inherit (settingsFormat) type; 80 description = '' 81 Homepage bookmarks configuration. 82 83 See <https://gethomepage.dev/configs/bookmarks/>. 84 ''; 85 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/bookmarks.yaml 86 example = [ 87 { 88 Developer = [ 89 { 90 Github = [ 91 { 92 abbr = "GH"; 93 href = "https://github.com/"; 94 } 95 ]; 96 } 97 ]; 98 } 99 { 100 Entertainment = [ 101 { 102 YouTube = [ 103 { 104 abbr = "YT"; 105 href = "https://youtube.com/"; 106 } 107 ]; 108 } 109 ]; 110 } 111 ]; 112 default = [ ]; 113 }; 114 115 services = lib.mkOption { 116 inherit (settingsFormat) type; 117 description = '' 118 Homepage services configuration. 119 120 See <https://gethomepage.dev/configs/services/>. 121 ''; 122 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/services.yaml 123 example = [ 124 { 125 "My First Group" = [ 126 { 127 "My First Service" = { 128 href = "http://localhost/"; 129 description = "Homepage is awesome"; 130 }; 131 } 132 ]; 133 } 134 { 135 "My Second Group" = [ 136 { 137 "My Second Service" = { 138 href = "http://localhost/"; 139 description = "Homepage is the best"; 140 }; 141 } 142 ]; 143 } 144 ]; 145 default = [ ]; 146 }; 147 148 widgets = lib.mkOption { 149 inherit (settingsFormat) type; 150 description = '' 151 Homepage widgets configuration. 152 153 See <https://gethomepage.dev/widgets/>. 154 ''; 155 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/widgets.yaml 156 example = [ 157 { 158 resources = { 159 cpu = true; 160 memory = true; 161 disk = "/"; 162 }; 163 } 164 { 165 search = { 166 provider = "duckduckgo"; 167 target = "_blank"; 168 }; 169 } 170 ]; 171 default = [ ]; 172 }; 173 174 kubernetes = lib.mkOption { 175 inherit (settingsFormat) type; 176 description = '' 177 Homepage kubernetes configuration. 178 179 See <https://gethomepage.dev/configs/kubernetes/>. 180 ''; 181 default = { }; 182 }; 183 184 docker = lib.mkOption { 185 inherit (settingsFormat) type; 186 description = '' 187 Homepage docker configuration. 188 189 See <https://gethomepage.dev/configs/docker/>. 190 ''; 191 default = { }; 192 }; 193 194 settings = lib.mkOption { 195 inherit (settingsFormat) type; 196 description = '' 197 Homepage settings. 198 199 See <https://gethomepage.dev/configs/settings/>. 200 ''; 201 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/settings.yaml 202 default = { }; 203 }; 204 }; 205 }; 206 207 config = lib.mkIf cfg.enable { 208 environment.etc = { 209 "homepage-dashboard/custom.css".text = cfg.customCSS; 210 "homepage-dashboard/custom.js".text = cfg.customJS; 211 "homepage-dashboard/bookmarks.yaml".source = settingsFormat.generate "bookmarks.yaml" cfg.bookmarks; 212 "homepage-dashboard/docker.yaml".source = settingsFormat.generate "docker.yaml" cfg.docker; 213 "homepage-dashboard/kubernetes.yaml".source = 214 settingsFormat.generate "kubernetes.yaml" cfg.kubernetes; 215 "homepage-dashboard/services.yaml".source = settingsFormat.generate "services.yaml" cfg.services; 216 "homepage-dashboard/settings.yaml".source = settingsFormat.generate "settings.yaml" cfg.settings; 217 "homepage-dashboard/widgets.yaml".source = settingsFormat.generate "widgets.yaml" cfg.widgets; 218 }; 219 220 systemd.services.homepage-dashboard = { 221 description = "Homepage Dashboard"; 222 after = [ "network.target" ]; 223 wantedBy = [ "multi-user.target" ]; 224 225 environment = { 226 HOMEPAGE_CONFIG_DIR = "/etc/homepage-dashboard"; 227 NIXPKGS_HOMEPAGE_CACHE_DIR = "/var/cache/homepage-dashboard"; 228 PORT = toString cfg.listenPort; 229 LOG_TARGETS = "stdout"; 230 HOMEPAGE_ALLOWED_HOSTS = cfg.allowedHosts; 231 }; 232 233 serviceConfig = { 234 Type = "simple"; 235 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; 236 StateDirectory = "homepage-dashboard"; 237 CacheDirectory = "homepage-dashboard"; 238 ExecStart = lib.getExe cfg.package; 239 Restart = "on-failure"; 240 241 # hardening 242 DynamicUser = true; 243 DevicePolicy = "closed"; 244 CapabilityBoundingSet = ""; 245 RestrictAddressFamilies = [ 246 "AF_INET" 247 "AF_INET6" 248 "AF_UNIX" 249 "AF_NETLINK" 250 ]; 251 DeviceAllow = ""; 252 NoNewPrivileges = true; 253 PrivateDevices = true; 254 PrivateMounts = true; 255 PrivateTmp = true; 256 PrivateUsers = true; 257 ProtectClock = true; 258 ProtectControlGroups = true; 259 ProtectHome = true; 260 ProtectKernelLogs = true; 261 ProtectKernelModules = true; 262 ProtectKernelTunables = true; 263 ProtectSystem = "strict"; 264 LockPersonality = true; 265 RemoveIPC = true; 266 RestrictNamespaces = true; 267 RestrictRealtime = true; 268 RestrictSUIDSGID = true; 269 SystemCallArchitectures = "native"; 270 SystemCallFilter = [ 271 "@system-service" 272 "~@resources" 273 ]; 274 ProtectProc = "invisible"; 275 ProtectHostname = true; 276 UMask = "0077"; 277 # cpu widget requires access to /proc 278 ProcSubset = if lib.any (widget: widget.resources.cpu or false) cfg.widgets then "all" else "pid"; 279 }; 280 281 enableStrictShellChecks = true; 282 283 # Related: 284 # * https://github.com/NixOS/nixpkgs/issues/346016 ("homepage-dashboard: cache dir is not cleared upon version upgrade") 285 # * https://github.com/gethomepage/homepage/discussions/4560 ("homepage NixOS package does not clear cache on upgrade leaving broken state") 286 # * https://github.com/vercel/next.js/discussions/58864 ("Feature Request: Allow configuration of cache dir") 287 preStart = '' 288 rm -rf "''${NIXPKGS_HOMEPAGE_CACHE_DIR:?}"/* 289 ''; 290 }; 291 292 networking.firewall = lib.mkIf cfg.openFirewall { 293 allowedTCPPorts = [ cfg.listenPort ]; 294 }; 295 }; 296}