1{ config
2, pkgs
3, lib
4, ...
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 environmentFile = lib.mkOption {
32 type = lib.types.str;
33 description = ''
34 The path to an environment file that contains environment variables to pass
35 to the homepage-dashboard service, for the purpose of passing secrets to
36 the service.
37
38 See the upstream documentation:
39
40 https://gethomepage.dev/latest/installation/docker/#using-environment-secrets
41 '';
42 default = "";
43 };
44
45 customCSS = lib.mkOption {
46 type = lib.types.lines;
47 description = ''
48 Custom CSS for styling Homepage.
49
50 See https://gethomepage.dev/latest/configs/custom-css-js/.
51 '';
52 default = "";
53 };
54
55 customJS = lib.mkOption {
56 type = lib.types.lines;
57 description = ''
58 Custom Javascript for Homepage.
59
60 See https://gethomepage.dev/latest/configs/custom-css-js/.
61 '';
62 default = "";
63 };
64
65 bookmarks = lib.mkOption {
66 inherit (settingsFormat) type;
67 description = ''
68 Homepage bookmarks configuration.
69
70 See https://gethomepage.dev/latest/configs/bookmarks/.
71 '';
72 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/bookmarks.yaml
73 example = [
74 {
75 Developer = [
76 { Github = [{ abbr = "GH"; href = "https://github.com/"; }]; }
77 ];
78 }
79 {
80 Entertainment = [
81 { YouTube = [{ abbr = "YT"; href = "https://youtube.com/"; }]; }
82 ];
83 }
84 ];
85 default = [ ];
86 };
87
88 services = lib.mkOption {
89 inherit (settingsFormat) type;
90 description = ''
91 Homepage services configuration.
92
93 See https://gethomepage.dev/latest/configs/services/.
94 '';
95 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/services.yaml
96 example = [
97 {
98 "My First Group" = [
99 {
100 "My First Service" = {
101 href = "http://localhost/";
102 description = "Homepage is awesome";
103 };
104 }
105 ];
106 }
107 {
108 "My Second Group" = [
109 {
110 "My Second Service" = {
111 href = "http://localhost/";
112 description = "Homepage is the best";
113 };
114 }
115 ];
116 }
117 ];
118 default = [ ];
119 };
120
121 widgets = lib.mkOption {
122 inherit (settingsFormat) type;
123 description = ''
124 Homepage widgets configuration.
125
126 See https://gethomepage.dev/latest/configs/service-widgets/.
127 '';
128 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/widgets.yaml
129 example = [
130 {
131 resources = {
132 cpu = true;
133 memory = true;
134 disk = "/";
135 };
136 }
137 {
138 search = {
139 provider = "duckduckgo";
140 target = "_blank";
141 };
142 }
143 ];
144 default = [ ];
145 };
146
147 kubernetes = lib.mkOption {
148 inherit (settingsFormat) type;
149 description = ''
150 Homepage kubernetes configuration.
151
152 See https://gethomepage.dev/latest/configs/kubernetes/.
153 '';
154 default = { };
155 };
156
157 docker = lib.mkOption {
158 inherit (settingsFormat) type;
159 description = ''
160 Homepage docker configuration.
161
162 See https://gethomepage.dev/latest/configs/docker/.
163 '';
164 default = { };
165 };
166
167 settings = lib.mkOption {
168 inherit (settingsFormat) type;
169 description = ''
170 Homepage settings.
171
172 See https://gethomepage.dev/latest/configs/settings/.
173 '';
174 # Defaults: https://github.com/gethomepage/homepage/blob/main/src/skeleton/settings.yaml
175 default = { };
176 };
177 };
178 };
179
180 config =
181 let
182 # If homepage-dashboard is enabled, but none of the configuration values have been updated,
183 # then default to "unmanaged" configuration which is manually updated in
184 # var/lib/homepage-dashboard. This is to maintain backwards compatibility, and should be
185 # deprecated in a future release.
186 managedConfig = !(
187 cfg.bookmarks == [ ] &&
188 cfg.customCSS == "" &&
189 cfg.customJS == "" &&
190 cfg.docker == { } &&
191 cfg.kubernetes == { } &&
192 cfg.services == [ ] &&
193 cfg.settings == { } &&
194 cfg.widgets == [ ]
195 );
196
197 configDir = if managedConfig then "/etc/homepage-dashboard" else "/var/lib/homepage-dashboard";
198
199 msg = "using unmanaged configuration for homepage-dashboard is deprecated and will be removed"
200 + " in 24.05. please see the NixOS documentation for `services.homepage-dashboard' and add"
201 + " your bookmarks, services, widgets, and other configuration using the options provided.";
202 in
203 lib.mkIf cfg.enable {
204 warnings = lib.optional (!managedConfig) msg;
205
206 environment.etc = lib.mkIf managedConfig {
207 "homepage-dashboard/custom.css".text = cfg.customCSS;
208 "homepage-dashboard/custom.js".text = cfg.customJS;
209
210 "homepage-dashboard/bookmarks.yaml".source = settingsFormat.generate "bookmarks.yaml" cfg.bookmarks;
211 "homepage-dashboard/docker.yaml".source = settingsFormat.generate "docker.yaml" cfg.docker;
212 "homepage-dashboard/kubernetes.yaml".source = settingsFormat.generate "kubernetes.yaml" cfg.kubernetes;
213 "homepage-dashboard/services.yaml".source = settingsFormat.generate "services.yaml" cfg.services;
214 "homepage-dashboard/settings.yaml".source = settingsFormat.generate "settings.yaml" cfg.settings;
215 "homepage-dashboard/widgets.yaml".source = settingsFormat.generate "widgets.yaml" cfg.widgets;
216 };
217
218 systemd.services.homepage-dashboard = {
219 description = "Homepage Dashboard";
220 after = [ "network.target" ];
221 wantedBy = [ "multi-user.target" ];
222
223 environment = {
224 HOMEPAGE_CONFIG_DIR = configDir;
225 PORT = toString cfg.listenPort;
226 LOG_TARGETS = lib.mkIf managedConfig "stdout";
227 };
228
229 serviceConfig = {
230 Type = "simple";
231 DynamicUser = true;
232 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
233 StateDirectory = lib.mkIf (!managedConfig) "homepage-dashboard";
234 ExecStart = lib.getExe cfg.package;
235 Restart = "on-failure";
236 };
237 };
238
239 networking.firewall = lib.mkIf cfg.openFirewall {
240 allowedTCPPorts = [ cfg.listenPort ];
241 };
242 };
243}