caddy: add virtualHosts stub
This commit is contained in:
parent
a629d25ad1
commit
abeef13d12
|
@ -995,7 +995,7 @@
|
||||||
./services/web-apps/youtrack.nix
|
./services/web-apps/youtrack.nix
|
||||||
./services/web-apps/zabbix.nix
|
./services/web-apps/zabbix.nix
|
||||||
./services/web-servers/apache-httpd/default.nix
|
./services/web-servers/apache-httpd/default.nix
|
||||||
./services/web-servers/caddy.nix
|
./services/web-servers/caddy/default.nix
|
||||||
./services/web-servers/darkhttpd.nix
|
./services/web-servers/darkhttpd.nix
|
||||||
./services/web-servers/fcgiwrap.nix
|
./services/web-servers/fcgiwrap.nix
|
||||||
./services/web-servers/hitch/default.nix
|
./services/web-servers/hitch/default.nix
|
||||||
|
|
|
@ -4,7 +4,17 @@ with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.services.caddy;
|
cfg = config.services.caddy;
|
||||||
configFile = pkgs.writeText "Caddyfile" cfg.config;
|
vhostToConfig = vhostName: vhostAttrs: ''
|
||||||
|
${vhostName} ${builtins.concatStringsSep " " vhostAttrs.serverAliases} {
|
||||||
|
${vhostAttrs.extraConfig}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
configFile = pkgs.writeText "Caddyfile" (builtins.concatStringsSep "\n"
|
||||||
|
([ cfg.config ] ++ (mapAttrsToList vhostToConfig cfg.virtualHosts)));
|
||||||
|
|
||||||
|
formattedConfig = pkgs.runCommand "formattedCaddyFile" { } ''
|
||||||
|
${cfg.package}/bin/caddy fmt ${configFile} > $out
|
||||||
|
'';
|
||||||
|
|
||||||
tlsConfig = {
|
tlsConfig = {
|
||||||
apps.tls.automation.policies = [{
|
apps.tls.automation.policies = [{
|
||||||
|
@ -17,7 +27,7 @@ let
|
||||||
|
|
||||||
adaptedConfig = pkgs.runCommand "caddy-config-adapted.json" { } ''
|
adaptedConfig = pkgs.runCommand "caddy-config-adapted.json" { } ''
|
||||||
${cfg.package}/bin/caddy adapt \
|
${cfg.package}/bin/caddy adapt \
|
||||||
--config ${configFile} --adapter ${cfg.adapter} > $out
|
--config ${formattedConfig} --adapter ${cfg.adapter} > $out
|
||||||
'';
|
'';
|
||||||
tlsJSON = pkgs.writeText "tls.json" (builtins.toJSON tlsConfig);
|
tlsJSON = pkgs.writeText "tls.json" (builtins.toJSON tlsConfig);
|
||||||
|
|
||||||
|
@ -68,6 +78,27 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
virtualHosts = mkOption {
|
||||||
|
type = types.attrsOf (types.submodule (import ./vhost-options.nix {
|
||||||
|
inherit config lib;
|
||||||
|
}));
|
||||||
|
default = { };
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
"hydra.example.com" = {
|
||||||
|
serverAliases = [ "www.hydra.example.com" ];
|
||||||
|
extraConfig = ''''''
|
||||||
|
encode gzip
|
||||||
|
log
|
||||||
|
root /srv/http
|
||||||
|
'''''';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
description = "Declarative vhost config";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
user = mkOption {
|
user = mkOption {
|
||||||
default = "caddy";
|
default = "caddy";
|
||||||
type = types.str;
|
type = types.str;
|
28
nixos/modules/services/web-servers/caddy/vhost-options.nix
Normal file
28
nixos/modules/services/web-servers/caddy/vhost-options.nix
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# This file defines the options that can be used both for the Nginx
|
||||||
|
# main server configuration, and for the virtual hosts. (The latter
|
||||||
|
# has additional options that affect the web server as a whole, like
|
||||||
|
# the user/group to run under.)
|
||||||
|
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
serverAliases = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [ "www.example.org" "example.org" ];
|
||||||
|
description = ''
|
||||||
|
Additional names of virtual hosts served by this virtual host configuration.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraConfig = mkOption {
|
||||||
|
type = types.lines;
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
These lines go into the vhost verbatim
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -43,49 +43,64 @@ import ./make-test-python.nix ({ pkgs, ... }: {
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
specialisation.multiple-configs.configuration = {
|
||||||
|
services.caddy.virtualHosts = {
|
||||||
|
"http://localhost:8080" = { };
|
||||||
|
"http://localhost:8081" = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
testScript = { nodes, ... }: let
|
testScript = { nodes, ... }:
|
||||||
etagSystem = "${nodes.webserver.config.system.build.toplevel}/specialisation/etag";
|
let
|
||||||
justReloadSystem = "${nodes.webserver.config.system.build.toplevel}/specialisation/config-reload";
|
etagSystem = "${nodes.webserver.config.system.build.toplevel}/specialisation/etag";
|
||||||
in ''
|
justReloadSystem = "${nodes.webserver.config.system.build.toplevel}/specialisation/config-reload";
|
||||||
url = "http://localhost/example.html"
|
multipleConfigs = "${nodes.webserver.config.system.build.toplevel}/specialisation/multiple-configs";
|
||||||
webserver.wait_for_unit("caddy")
|
in
|
||||||
webserver.wait_for_open_port("80")
|
''
|
||||||
|
url = "http://localhost/example.html"
|
||||||
|
webserver.wait_for_unit("caddy")
|
||||||
|
webserver.wait_for_open_port("80")
|
||||||
|
|
||||||
|
|
||||||
def check_etag(url):
|
def check_etag(url):
|
||||||
etag = webserver.succeed(
|
etag = webserver.succeed(
|
||||||
"curl --fail -v '{}' 2>&1 | sed -n -e \"s/^< [Ee][Tt][Aa][Gg]: *//p\"".format(
|
"curl --fail -v '{}' 2>&1 | sed -n -e \"s/^< [Ee][Tt][Aa][Gg]: *//p\"".format(
|
||||||
url
|
url
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
etag = etag.replace("\r\n", " ")
|
||||||
etag = etag.replace("\r\n", " ")
|
http_code = webserver.succeed(
|
||||||
http_code = webserver.succeed(
|
"curl --fail --silent --show-error -o /dev/null -w \"%{{http_code}}\" --head -H 'If-None-Match: {}' {}".format(
|
||||||
"curl --fail --silent --show-error -o /dev/null -w \"%{{http_code}}\" --head -H 'If-None-Match: {}' {}".format(
|
etag, url
|
||||||
etag, url
|
)
|
||||||
)
|
)
|
||||||
)
|
assert int(http_code) == 304, "HTTP code is {}, expected 304".format(http_code)
|
||||||
assert int(http_code) == 304, "HTTP code is {}, expected 304".format(http_code)
|
return etag
|
||||||
return etag
|
|
||||||
|
|
||||||
|
|
||||||
with subtest("check ETag if serving Nix store paths"):
|
with subtest("check ETag if serving Nix store paths"):
|
||||||
old_etag = check_etag(url)
|
old_etag = check_etag(url)
|
||||||
webserver.succeed(
|
webserver.succeed(
|
||||||
"${etagSystem}/bin/switch-to-configuration test >&2"
|
"${etagSystem}/bin/switch-to-configuration test >&2"
|
||||||
)
|
)
|
||||||
webserver.sleep(1)
|
webserver.sleep(1)
|
||||||
new_etag = check_etag(url)
|
new_etag = check_etag(url)
|
||||||
assert old_etag != new_etag, "Old ETag {} is the same as {}".format(
|
assert old_etag != new_etag, "Old ETag {} is the same as {}".format(
|
||||||
old_etag, new_etag
|
old_etag, new_etag
|
||||||
)
|
)
|
||||||
|
|
||||||
with subtest("config is reloaded on nixos-rebuild switch"):
|
with subtest("config is reloaded on nixos-rebuild switch"):
|
||||||
webserver.succeed(
|
webserver.succeed(
|
||||||
"${justReloadSystem}/bin/switch-to-configuration test >&2"
|
"${justReloadSystem}/bin/switch-to-configuration test >&2"
|
||||||
)
|
)
|
||||||
webserver.wait_for_open_port("8080")
|
webserver.wait_for_open_port("8080")
|
||||||
'';
|
|
||||||
})
|
with subtest("multiple configs are correctly merged"):
|
||||||
|
webserver.succeed(
|
||||||
|
"${multipleConfigs}/bin/switch-to-configuration test >&2"
|
||||||
|
)
|
||||||
|
webserver.wait_for_open_port("8080")
|
||||||
|
webserver.wait_for_open_port("8081")
|
||||||
|
'';
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in a new issue