at master 9.2 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.port; 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 proxmox = lib.mkOption { 195 inherit (settingsFormat) type; 196 description = '' 197 Homepage proxmox configuration. 198 199 See <https://gethomepage.dev/configs/proxmox/>. 200 ''; 201 default = { }; 202 }; 203 204 settings = lib.mkOption { 205 inherit (settingsFormat) type; 206 description = '' 207 Homepage settings. 208 209 See <https://gethomepage.dev/configs/settings/>. 210 ''; 211 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/settings.yaml 212 default = { }; 213 }; 214 }; 215 }; 216 217 config = lib.mkIf cfg.enable { 218 environment.etc = { 219 "homepage-dashboard/custom.css".text = cfg.customCSS; 220 "homepage-dashboard/custom.js".text = cfg.customJS; 221 "homepage-dashboard/bookmarks.yaml".source = settingsFormat.generate "bookmarks.yaml" cfg.bookmarks; 222 "homepage-dashboard/docker.yaml".source = settingsFormat.generate "docker.yaml" cfg.docker; 223 "homepage-dashboard/kubernetes.yaml".source = 224 settingsFormat.generate "kubernetes.yaml" cfg.kubernetes; 225 "homepage-dashboard/services.yaml".source = settingsFormat.generate "services.yaml" cfg.services; 226 "homepage-dashboard/settings.yaml".source = settingsFormat.generate "settings.yaml" cfg.settings; 227 "homepage-dashboard/widgets.yaml".source = settingsFormat.generate "widgets.yaml" cfg.widgets; 228 "homepage-dashboard/proxmox.yaml".source = settingsFormat.generate "proxmox.yaml" cfg.proxmox; 229 }; 230 231 systemd.services.homepage-dashboard = { 232 description = "Homepage Dashboard"; 233 after = [ "network.target" ]; 234 wantedBy = [ "multi-user.target" ]; 235 236 environment = { 237 HOMEPAGE_CONFIG_DIR = "/etc/homepage-dashboard"; 238 NIXPKGS_HOMEPAGE_CACHE_DIR = "/var/cache/homepage-dashboard"; 239 PORT = toString cfg.listenPort; 240 LOG_TARGETS = "stdout"; 241 HOMEPAGE_ALLOWED_HOSTS = cfg.allowedHosts; 242 }; 243 244 serviceConfig = { 245 Type = "simple"; 246 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile; 247 StateDirectory = "homepage-dashboard"; 248 CacheDirectory = "homepage-dashboard"; 249 ExecStart = lib.getExe cfg.package; 250 Restart = "on-failure"; 251 252 # hardening 253 DynamicUser = true; 254 DevicePolicy = "closed"; 255 CapabilityBoundingSet = ""; 256 RestrictAddressFamilies = [ 257 "AF_INET" 258 "AF_INET6" 259 "AF_UNIX" 260 "AF_NETLINK" 261 ]; 262 DeviceAllow = ""; 263 NoNewPrivileges = true; 264 PrivateDevices = true; 265 PrivateMounts = true; 266 PrivateTmp = true; 267 PrivateUsers = true; 268 ProtectClock = true; 269 ProtectControlGroups = true; 270 ProtectHome = true; 271 ProtectKernelLogs = true; 272 ProtectKernelModules = true; 273 ProtectKernelTunables = true; 274 ProtectSystem = "strict"; 275 LockPersonality = true; 276 RemoveIPC = true; 277 RestrictNamespaces = true; 278 RestrictRealtime = true; 279 RestrictSUIDSGID = true; 280 SystemCallArchitectures = "native"; 281 SystemCallFilter = [ 282 "@system-service" 283 "~@resources" 284 ]; 285 ProtectProc = "invisible"; 286 ProtectHostname = true; 287 UMask = "0077"; 288 # cpu widget requires access to /proc 289 ProcSubset = if lib.any (widget: widget.resources.cpu or false) cfg.widgets then "all" else "pid"; 290 }; 291 292 enableStrictShellChecks = true; 293 294 # Related: 295 # * https://github.com/NixOS/nixpkgs/issues/346016 ("homepage-dashboard: cache dir is not cleared upon version upgrade") 296 # * https://github.com/gethomepage/homepage/discussions/4560 ("homepage NixOS package does not clear cache on upgrade leaving broken state") 297 # * https://github.com/vercel/next.js/discussions/58864 ("Feature Request: Allow configuration of cache dir") 298 preStart = '' 299 rm -rf "''${NIXPKGS_HOMEPAGE_CACHE_DIR:?}"/* 300 ''; 301 }; 302 303 networking.firewall = lib.mkIf cfg.openFirewall { 304 allowedTCPPorts = [ cfg.listenPort ]; 305 }; 306 }; 307}