diff --git a/lib/make-webservice.nix b/lib/make-webservice.nix index edf3ec3..3297935 100644 --- a/lib/make-webservice.nix +++ b/lib/make-webservice.nix @@ -11,6 +11,7 @@ wsName: module: ../modules/web/webserver/apache.nix ../modules/web/webserver/lighttpd.nix ../modules/web/webserver/nginx.nix + ../modules/web/webserver/darkhttpd.nix ]; _module.args = { inherit wsName pkgs toplevel; }; }); diff --git a/modules/web/core/base.nix b/modules/web/core/base.nix index d9b87af..b58ecf1 100644 --- a/modules/web/core/base.nix +++ b/modules/web/core/base.nix @@ -54,7 +54,7 @@ in { }; webserver.variant = lib.mkOption { - type = lib.types.nullOr (lib.types.enum [ "apache" "lighttpd" "nginx" ]); + type = lib.types.nullOr (lib.types.enum [ "apache" "lighttpd" "nginx" "darkhttpd" ]); default = null; description = "The webserver module to use for this webservice."; }; diff --git a/modules/web/default.nix b/modules/web/default.nix index 01a8b33..91db967 100644 --- a/modules/web/default.nix +++ b/modules/web/default.nix @@ -2,9 +2,10 @@ { imports = lib.mapAttrsToList (import ../../lib/make-webservice.nix) { - filesender = services/filesender; - leaps = services/leaps; - mediawiki = services/mediawiki; + filesender = services/filesender; + leaps = services/leaps; + mediawiki = services/mediawiki; + static-darkhttpd = services/static-darkhttpd; }; config = let diff --git a/modules/web/services/static-darkhttpd/default.nix b/modules/web/services/static-darkhttpd/default.nix new file mode 100644 index 0000000..144543d --- /dev/null +++ b/modules/web/services/static-darkhttpd/default.nix @@ -0,0 +1,19 @@ +{ config, lib, pkgs, wsName, mkUnique, darkhttpd, ... }: + +with lib; + +{ + options = {}; + + config = rec { + webserver.variant = "darkhttpd"; + tests.wanted = [ ./test.nix ]; + }; + + meta = { + description = "Using darkhttpd for static file serving (no CGI)"; + maintainers = with maintainers; [ qknight ]; + license = lib.licenses.bsd2; + homepage = https://github.com/nixcloud/nixcloud-webservices; + }; +} diff --git a/modules/web/services/static-darkhttpd/test.nix b/modules/web/services/static-darkhttpd/test.nix new file mode 100644 index 0000000..6d45f0e --- /dev/null +++ b/modules/web/services/static-darkhttpd/test.nix @@ -0,0 +1,30 @@ +{ + name = "static-darkhttpd"; + + machine.imports = [ ../../../../tests/common/eatmydata.nix ]; + machine.nixcloud.reverse-proxy.enable = true; + machine.nixcloud.reverse-proxy.extendEtcHosts = true; + machine.nixcloud.webservices.static-darkhttpd = { + foo.enable = true; + foo.proxyOptions.TLS = "none"; + foo.proxyOptions.domain = "example.com"; + foo.proxyOptions.http.mode = "on"; + foo.proxyOptions.https.mode = "off"; + foo.proxyOptions.port = 8080; + + bar.enable = true; + bar.proxyOptions.TLS = "none"; + bar.proxyOptions.domain = "example.org"; + bar.proxyOptions.http.mode = "on"; + bar.proxyOptions.https.mode = "off"; + bar.proxyOptions.port = 8081; + }; + + testScript = let + searchFor = "Generated by darkhttpd"; + in '' + $machine->waitForUnit('multi-user.target'); + $machine->succeed('curl -L http://example.com/ | grep -qF "${searchFor}"'); + $machine->succeed('curl -L http://example.org/ | grep -qF "${searchFor}"'); + ''; +} diff --git a/modules/web/webserver/darkhttpd.nix b/modules/web/webserver/darkhttpd.nix new file mode 100644 index 0000000..cf85c24 --- /dev/null +++ b/modules/web/webserver/darkhttpd.nix @@ -0,0 +1,52 @@ +{ config, pkgs, lib, options, wsName, mkUnique, ... }: + +with lib; + +{ + options.webserver.darkhttpd = { + extraServiceDependencies = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "postgresql.service" ]; + description = "Makes it easy to replace postgresql by mysql and depend on the service before we start the webservice."; + }; + }; + + config = mkIf (config.webserver.variant == "darkhttpd" && config.enable) { + directories.log = { + permissions.defaultDirectoryMode = "0750"; + permissions.others.noAccess = true; + owner = mkUnique config.webserver.user; + group = mkUnique config.webserver.group; + instance.before = [ "webserver-init.service" "instance-init.target" ]; + }; + + systemd.services.darkhttpd = { + description = "${config.uniqueName} main service (darkhttpd)"; + wantedBy = [ "multi-user.target" ]; + wants = [ "keys.target" ]; + after = [ "network.target" "fs.target" "keys.target" ]; + instance.after = [ "database.target" "webserver-init.service" ]; + + serviceConfig = { + ExecStart = "${pkgs.darkhttpd}/bin/darkhttpd ${config.stateDir} --port ${toString config.proxyOptions.port} --addr 127.0.0.1"; + KillSignal = "SIGTERM"; + Restart = "always"; + RestartSec = "10s"; + StartLimitInterval = "1min"; + User = config.webserver.user; + Group = config.webserver.group; + PermissionsStartOnly = true; + PrivateTmp = config.webserver.privateTmp; + WorkingDirectory = config.stateDir; + MemoryDenyWriteExecute = true; + RestrictNameSpaces = true; + NoNewPrivileges = true; + ProtectHome = true; + PrivateUsers = true; + ProtectSystem = true; + ProtectKernelTunables = true; + }; + }; + }; +}