grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / web-servers / bluemap.nix
blob731468fd9a0ec79b0e51c63f1d78dd3d882c2047
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.services.bluemap;
4   format = pkgs.formats.hocon { };
6   coreConfig = format.generate "core.conf" cfg.coreSettings;
7   webappConfig = format.generate "webapp.conf" cfg.webappSettings;
8   webserverConfig = format.generate "webserver.conf" cfg.webserverSettings;
10   mapsFolder = pkgs.linkFarm "maps"
11     (lib.attrsets.mapAttrs' (name: value:
12       lib.nameValuePair "${name}.conf"
13         (format.generate "${name}.conf" value))
14       cfg.maps);
16   storageFolder = pkgs.linkFarm "storage"
17     (lib.attrsets.mapAttrs' (name: value:
18       lib.nameValuePair "${name}.conf"
19         (format.generate "${name}.conf" value))
20       cfg.storage);
22   configFolder = pkgs.linkFarm "bluemap-config" {
23     "maps" = mapsFolder;
24     "storages" = storageFolder;
25     "core.conf" = coreConfig;
26     "webapp.conf" = webappConfig;
27     "webserver.conf" = webserverConfig;
28     "resourcepacks" = pkgs.linkFarm "resourcepacks" cfg.resourcepacks;
29   };
31   inherit (lib) mkOption;
32 in {
33   options.services.bluemap = {
34     enable = lib.mkEnableOption "bluemap";
36     eula = mkOption {
37       type = lib.types.bool;
38       description = ''
39         By changing this option to true you confirm that you own a copy of minecraft Java Edition,
40         and that you agree to minecrafts EULA.
41       '';
42       default = false;
43     };
45     defaultWorld = mkOption {
46       type = lib.types.path;
47       description = ''
48         The world used by the default map ruleset.
49         If you configure your own maps you do not need to set this.
50       '';
51       example = lib.literalExpression "\${config.services.minecraft.dataDir}/world";
52     };
54     enableRender = mkOption {
55       type = lib.types.bool;
56       description = "Enable rendering";
57       default = true;
58     };
60     webRoot = mkOption {
61       type = lib.types.path;
62       default = "/var/lib/bluemap/web";
63       description = "The directory for saving and serving the webapp and the maps";
64     };
66     enableNginx = mkOption {
67       type = lib.types.bool;
68       default = true;
69       description = "Enable configuring a virtualHost for serving the bluemap webapp";
70     };
72     host = mkOption {
73       type = lib.types.str;
74       description = "Domain on which nginx will serve the bluemap webapp";
75     };
77     onCalendar = mkOption {
78       type = lib.types.str;
79       description = ''
80         How often to trigger rendering the map,
81         in the format of a systemd timer onCalendar configuration.
82         See {manpage}`systemd.timer(5)`.
83       '';
84       default = "*-*-* 03:10:00";
85     };
87     coreSettings = mkOption {
88       type = lib.types.submodule {
89         freeformType = format.type;
90         options = {
91           data = mkOption {
92             type = lib.types.path;
93             description = "Folder for where bluemap stores its data";
94             default = "/var/lib/bluemap";
95           };
96           metrics = lib.mkEnableOption "Sending usage metrics containing the version of bluemap in use";
97         };
98       };
99       description = "Settings for the core.conf file, [see upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/core.conf).";
100     };
102     webappSettings = mkOption {
103       type = lib.types.submodule {
104         freeformType = format.type;
105       };
106       default = {
107         enabled = true;
108         webroot = cfg.webRoot;
109       };
110       defaultText = lib.literalExpression ''
111         {
112           enabled = true;
113           webroot = config.services.bluemap.webRoot;
114         }
115       '';
116       description = "Settings for the webapp.conf file, see [upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/webapp.conf).";
117     };
119     webserverSettings = mkOption {
120       type = lib.types.submodule {
121         freeformType = format.type;
122         options = {
123           enabled = mkOption {
124             type = lib.types.bool;
125             description = ''
126               Enable bluemap's built-in webserver.
127               Disabled by default in nixos for use of nginx directly.
128             '';
129             default = false;
130           };
131         };
132       };
133       default = { };
134       description = ''
135         Settings for the webserver.conf file, usually not required.
136         [See upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/webserver.conf).
137       '';
138     };
140     maps = mkOption {
141       type = lib.types.attrsOf (lib.types.submodule {
142         freeformType = format.type;
143         options = {
144           world = lib.mkOption {
145             type = lib.types.path;
146             description = "Path to world folder containing the dimension to render";
147           };
148         };
149       });
150       default = {
151         "overworld" = {
152           world = "${cfg.defaultWorld}";
153           ambient-light = 0.1;
154           cave-detection-ocean-floor = -5;
155         };
157         "nether" = {
158           world = "${cfg.defaultWorld}/DIM-1";
159           sorting = 100;
160           sky-color = "#290000";
161           void-color = "#150000";
162           ambient-light = 0.6;
163           world-sky-light = 0;
164           remove-caves-below-y = -10000;
165           cave-detection-ocean-floor = -5;
166           cave-detection-uses-block-light = true;
167           max-y = 90;
168         };
170         "end" = {
171           world = "${cfg.defaultWorld}/DIM1";
172           sorting = 200;
173           sky-color = "#080010";
174           void-color = "#080010";
175           ambient-light = 0.6;
176           world-sky-light = 0;
177           remove-caves-below-y = -10000;
178           cave-detection-ocean-floor = -5;
179         };
180       };
181       defaultText = lib.literalExpression ''
182         {
183           "overworld" = {
184             world = "''${cfg.defaultWorld}";
185             ambient-light = 0.1;
186             cave-detection-ocean-floor = -5;
187           };
189           "nether" = {
190             world = "''${cfg.defaultWorld}/DIM-1";
191             sorting = 100;
192             sky-color = "#290000";
193             void-color = "#150000";
194             ambient-light = 0.6;
195             world-sky-light = 0;
196             remove-caves-below-y = -10000;
197             cave-detection-ocean-floor = -5;
198             cave-detection-uses-block-light = true;
199             max-y = 90;
200           };
202           "end" = {
203             world = "''${cfg.defaultWorld}/DIM1";
204             sorting = 200;
205             sky-color = "#080010";
206             void-color = "#080010";
207             ambient-light = 0.6;
208             world-sky-light = 0;
209             remove-caves-below-y = -10000;
210             cave-detection-ocean-floor = -5;
211           };
212         };
213       '';
214       description = ''
215         Settings for files in `maps/`.
216         If you define anything here you must define everything yourself.
217         See the default for an example with good options for the different world types.
218         For valid values [consult upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/blob/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/maps/map.conf).
219       '';
220     };
222     storage = mkOption {
223       type = lib.types.attrsOf (lib.types.submodule {
224         freeformType = format.type;
225         options = {
226           storage-type = mkOption {
227             type = lib.types.enum [ "FILE" "SQL" ];
228             description = "Type of storage config";
229             default = "FILE";
230           };
231         };
232       });
233       description = ''
234         Where the rendered map will be stored.
235         Unless you are doing something advanced you should probably leave this alone and configure webRoot instead.
236         [See upstream docs](https://github.com/BlueMap-Minecraft/BlueMap/tree/master/BlueMapCommon/src/main/resources/de/bluecolored/bluemap/config/storages)
237       '';
238       default = {
239         "file" = {
240           root = "${cfg.webRoot}/maps";
241         };
242       };
243       defaultText = lib.literalExpression ''
244         {
245           "file" = {
246             root = "''${config.services.bluemap.webRoot}/maps";
247           };
248         }
249       '';
250     };
252     resourcepacks = mkOption {
253       type = lib.types.attrsOf lib.types.pathInStore;
254       default = { };
255       description = "A set of resourcepacks to use, loaded in alphabetical order";
256     };
257   };
260   config = lib.mkIf cfg.enable {
261     assertions =
262       [ { assertion = config.services.bluemap.eula;
263           message = ''
264             You have enabled bluemap but have not accepted minecraft's EULA.
265             You can achieve this through setting `services.bluemap.eula = true`
266           '';
267         }
268       ];
270     services.bluemap.coreSettings.accept-download = cfg.eula;
272     systemd.services."render-bluemap-maps" = lib.mkIf cfg.enableRender {
273       serviceConfig = {
274         Type = "oneshot";
275         Group = "nginx";
276         UMask = "026";
277       };
278       script = ''
279         ${lib.getExe pkgs.bluemap} -c ${configFolder} -gs -r
280       '';
281     };
283     systemd.timers."render-bluemap-maps" = lib.mkIf cfg.enableRender {
284       wantedBy = [ "timers.target" ];
285       timerConfig = {
286         OnCalendar = cfg.onCalendar;
287         Persistent = true;
288         Unit = "render-bluemap-maps.service";
289       };
290     };
292     services.nginx.virtualHosts = lib.mkIf cfg.enableNginx {
293       "${cfg.host}" = {
294         root = config.services.bluemap.webRoot;
295         locations = {
296           "~* ^/maps/[^/]*/tiles/[^/]*.json$".extraConfig = ''
297             error_page 404 =200 /assets/emptyTile.json;
298             gzip_static always;
299           '';
300           "~* ^/maps/[^/]*/tiles/[^/]*.png$".tryFiles = "$uri =204";
301         };
302       };
303     };
304   };
306   meta = {
307     maintainers = with lib.maintainers; [ dandellion h7x4 ];
308   };