1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8let
9 cfg = config.services.static-web-server;
10 toml = pkgs.formats.toml { };
11 configFilePath = toml.generate "config.toml" cfg.configuration;
12in
13{
14 options = {
15 services.static-web-server = {
16 enable = lib.mkEnableOption ''Static Web Server'';
17 listen = lib.mkOption {
18 default = "[::]:8787";
19 type = lib.types.str;
20 description = ''
21 The {manpage}`systemd.socket(5)` "ListenStream" used in static-web-server.socket.
22 This is equivalent to SWS's "host" and "port" options.
23 See here for specific syntax: <https://www.freedesktop.org/software/systemd/man/systemd.socket.html#ListenStream=>
24 '';
25 };
26 root = lib.mkOption {
27 type = lib.types.path;
28 description = ''
29 The location of files for SWS to serve. Equivalent to SWS's "root" config value.
30 NOTE: This folder must exist before starting SWS.
31 '';
32 };
33 configuration = lib.mkOption {
34 default = { };
35 type = toml.type;
36 example = {
37 general = {
38 log-level = "error";
39 directory-listing = true;
40 };
41 };
42 description = ''
43 Configuration for Static Web Server. See
44 <https://static-web-server.net/configuration/config-file/>.
45 NOTE: Don't set "host", "port", or "root" here. They will be ignored.
46 Use the top-level "listen" and "root" options instead.
47 '';
48 };
49 };
50 };
51
52 config = lib.mkIf cfg.enable {
53 environment.systemPackages = [ pkgs.static-web-server ];
54 systemd.packages = [ pkgs.static-web-server ];
55 # Have to set wantedBy since systemd.packages ignores the "Install" section
56 systemd.sockets.static-web-server = {
57 wantedBy = [ "sockets.target" ];
58 # Start with empty string to reset upstream option
59 listenStreams = [
60 ""
61 cfg.listen
62 ];
63 };
64 systemd.services.static-web-server = {
65 wantedBy = [ "multi-user.target" ];
66 serviceConfig = {
67 # Remove upstream sample environment file; use config.toml exclusively
68 EnvironmentFile = [ "" ];
69 ExecStart = [
70 ""
71 "${pkgs.static-web-server}/bin/static-web-server --fd 0 --config-file ${configFilePath} --root ${cfg.root}"
72 ];
73 # Supplementary groups doesn't work unless we create the group ourselves
74 SupplementaryGroups = [ "" ];
75 # If the user is serving files from their home dir, override ProtectHome to allow that
76 ProtectHome = if lib.hasPrefix "/home" cfg.root then "tmpfs" else "true";
77 BindReadOnlyPaths = cfg.root;
78 };
79 };
80 };
81
82 meta.maintainers = with lib.maintainers; [ mac-chaffee ];
83}