1{ pkgs, ... }:
2{
3 name = "caddy";
4 meta = with pkgs.lib.maintainers; {
5 maintainers = [
6 Br1ght0ne
7 stepbrobd
8 ];
9 };
10
11 nodes = {
12 webserver =
13 { pkgs, ... }:
14 {
15 services.caddy.enable = true;
16 services.caddy.extraConfig = ''
17 http://localhost {
18 encode gzip
19
20 file_server
21 root * ${
22 pkgs.runCommand "testdir" { } ''
23 mkdir "$out"
24 echo hello world > "$out/example.html"
25 ''
26 }
27 }
28 '';
29 services.caddy.enableReload = true;
30
31 specialisation.config-reload.configuration = {
32 services.caddy.extraConfig = ''
33 http://localhost:8080 {
34 }
35 '';
36 };
37 specialisation.multiple-configs.configuration = {
38 services.caddy.virtualHosts = {
39 "http://localhost:8080" = { };
40 "http://localhost:8081" = { };
41 };
42 };
43 specialisation.multiple-hostnames.configuration = {
44 services.caddy.virtualHosts = {
45 "http://localhost:8080 http://localhost:8081" = { };
46 };
47 };
48 specialisation.rfc42.configuration = {
49 services.caddy.settings = {
50 apps.http.servers.default = {
51 listen = [ ":80" ];
52 routes = [
53 {
54 handle = [
55 {
56 body = "hello world";
57 handler = "static_response";
58 status_code = 200;
59 }
60 ];
61 }
62 ];
63 };
64 };
65 };
66 specialisation.explicit-config-file.configuration = {
67 services.caddy.configFile = pkgs.writeText "Caddyfile" ''
68 localhost:80
69
70 respond "hello world"
71 '';
72 };
73 specialisation.with-plugins.configuration = {
74 services.caddy = {
75 package = pkgs.caddy.withPlugins {
76 plugins = [ "github.com/caddyserver/replace-response@v0.0.0-20241211194404-3865845790a7" ];
77 hash = "sha256-RrB0/qXL0mCvkxKaz8zhj5GWKEtOqItXP2ASYz7VdMU=";
78 };
79 configFile = pkgs.writeText "Caddyfile" ''
80 {
81 order replace after encode
82 }
83
84 localhost:80 {
85 respond "hello world"
86 replace world caddy
87 }
88 '';
89 };
90 };
91 };
92 };
93
94 testScript =
95 { nodes, ... }:
96 let
97 explicitConfigFile = "${nodes.webserver.system.build.toplevel}/specialisation/explicit-config-file";
98 justReloadSystem = "${nodes.webserver.system.build.toplevel}/specialisation/config-reload";
99 multipleConfigs = "${nodes.webserver.system.build.toplevel}/specialisation/multiple-configs";
100 multipleHostnames = "${nodes.webserver.system.build.toplevel}/specialisation/multiple-hostnames";
101 rfc42Config = "${nodes.webserver.system.build.toplevel}/specialisation/rfc42";
102 withPluginsConfig = "${nodes.webserver.system.build.toplevel}/specialisation/with-plugins";
103 in
104 ''
105 url = "http://localhost/example.html"
106 webserver.wait_for_unit("caddy")
107 webserver.wait_for_open_port(80)
108
109
110 with subtest("config is reloaded on nixos-rebuild switch"):
111 webserver.succeed(
112 "${justReloadSystem}/bin/switch-to-configuration test >&2"
113 )
114 webserver.wait_for_open_port(8080)
115 webserver.fail("journalctl -u caddy | grep -q -i stopped")
116 webserver.succeed("journalctl -u caddy | grep -q -i reloaded")
117
118 with subtest("multiple configs are correctly merged"):
119 webserver.succeed(
120 "${multipleConfigs}/bin/switch-to-configuration test >&2"
121 )
122 webserver.wait_for_open_port(8080)
123 webserver.wait_for_open_port(8081)
124
125 with subtest("a virtual host with multiple hostnames works"):
126 webserver.succeed(
127 "${multipleHostnames}/bin/switch-to-configuration test >&2"
128 )
129 webserver.wait_for_open_port(8080)
130 webserver.wait_for_open_port(8081)
131
132 with subtest("rfc42 settings config"):
133 webserver.succeed(
134 "${rfc42Config}/bin/switch-to-configuration test >&2"
135 )
136 webserver.wait_for_open_port(80)
137 webserver.succeed("curl http://localhost | grep hello")
138
139 with subtest("explicit configFile"):
140 webserver.succeed(
141 "${explicitConfigFile}/bin/switch-to-configuration test >&2"
142 )
143 webserver.wait_for_open_port(80)
144 webserver.succeed("curl http://localhost | grep hello")
145
146 with subtest("plugins are correctled installed and configurable"):
147 webserver.succeed(
148 "${withPluginsConfig}/bin/switch-to-configuration test >&2"
149 )
150 webserver.wait_for_open_port(80)
151 webserver.succeed("curl http://localhost | grep caddy")
152 '';
153}