Merge pull request #97217 from sephii/nixos-caddy-v2-migration

This commit is contained in:
Oleksii Filonenko 2020-09-08 11:17:55 +03:00 committed by GitHub
commit 45d7f59da8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 119 additions and 67 deletions

View File

@ -796,6 +796,15 @@ CREATE ROLE postgres LOGIN SUPERUSER;
<literal>config.systemd.services.${name}.path</literal> now returns a list of paths instead of a colon-separated string. <literal>config.systemd.services.${name}.path</literal> now returns a list of paths instead of a colon-separated string.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Caddy module now uses Caddy v2 by default. Caddy v1 can still be used by setting
<xref linkend="opt-services.caddy.package"/> to <literal>pkgs.caddy1</literal>.
</para>
<para>
New option <xref linkend="opt-services.caddy.adapter"/> has been added.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>

View File

@ -5,6 +5,26 @@ with lib;
let let
cfg = config.services.caddy; cfg = config.services.caddy;
configFile = pkgs.writeText "Caddyfile" cfg.config; configFile = pkgs.writeText "Caddyfile" cfg.config;
# v2-specific options
isCaddy2 = versionAtLeast cfg.package.version "2.0";
tlsConfig = {
apps.tls.automation.policies = [{
issuer = {
inherit (cfg) ca email;
module = "acme";
};
}];
};
adaptedConfig = pkgs.runCommand "caddy-config-adapted.json" { } ''
${cfg.package}/bin/caddy adapt \
--config ${configFile} --adapter ${cfg.adapter} > $out
'';
tlsJSON = pkgs.writeText "tls.json" (builtins.toJSON tlsConfig);
configJSON = pkgs.runCommand "caddy-config.json" { } ''
${pkgs.jq}/bin/jq -s '.[0] * .[1]' ${adaptedConfig} ${tlsJSON} > $out
'';
in { in {
options.services.caddy = { options.services.caddy = {
enable = mkEnableOption "Caddy web server"; enable = mkEnableOption "Caddy web server";
@ -13,15 +33,26 @@ in {
default = ""; default = "";
example = '' example = ''
example.com { example.com {
gzip encode gzip
minify log
log syslog root /srv/http
root /srv/http
} }
''; '';
type = types.lines; type = types.lines;
description = "Verbatim Caddyfile to use"; description = ''
Verbatim Caddyfile to use.
Caddy v2 supports multiple config formats via adapters (see <option>services.caddy.adapter</option>).
'';
};
adapter = mkOption {
default = "caddyfile";
example = "nginx";
type = types.str;
description = ''
Name of the config adapter to use. Not applicable to Caddy v1.
See https://caddyserver.com/docs/config-adapters for the full list.
'';
}; };
ca = mkOption { ca = mkOption {
@ -50,33 +81,46 @@ in {
The data directory, for storing certificates. Before 17.09, this The data directory, for storing certificates. Before 17.09, this
would create a .caddy directory. With 17.09 the contents of the would create a .caddy directory. With 17.09 the contents of the
.caddy directory are in the specified data directory instead. .caddy directory are in the specified data directory instead.
Caddy v2 replaced CADDYPATH with XDG directories.
See https://caddyserver.com/docs/conventions#file-locations.
''; '';
}; };
package = mkOption { package = mkOption {
default = pkgs.caddy; default = pkgs.caddy;
defaultText = "pkgs.caddy"; defaultText = "pkgs.caddy";
example = "pkgs.caddy1";
type = types.package; type = types.package;
description = "Caddy package to use."; description = ''
Caddy package to use.
To use Caddy v1 (obsolete), set this to <literal>pkgs.caddy1</literal>.
'';
}; };
}; };
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services.caddy = { systemd.services.caddy = {
description = "Caddy web server"; description = "Caddy web server";
# upstream unit: https://github.com/caddyserver/caddy/blob/master/dist/init/linux-systemd/caddy.service # upstream unit: https://github.com/caddyserver/dist/blob/master/init/caddy.service
after = [ "network-online.target" ]; after = [ "network-online.target" ];
wants = [ "network-online.target" ]; # systemd-networkd-wait-online.service wants = [ "network-online.target" ]; # systemd-networkd-wait-online.service
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
environment = mkIf (versionAtLeast config.system.stateVersion "17.09") environment = mkIf (versionAtLeast config.system.stateVersion "17.09" && !isCaddy2)
{ CADDYPATH = cfg.dataDir; }; { CADDYPATH = cfg.dataDir; };
serviceConfig = { serviceConfig = {
ExecStart = '' ExecStart = if isCaddy2 then ''
${cfg.package}/bin/caddy run --config ${configJSON}
'' else ''
${cfg.package}/bin/caddy -log stdout -log-timestamps=false \ ${cfg.package}/bin/caddy -log stdout -log-timestamps=false \
-root=/var/tmp -conf=${configFile} \ -root=/var/tmp -conf=${configFile} \
-ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"} -ca=${cfg.ca} -email=${cfg.email} ${optionalString cfg.agree "-agree"}
''; '';
ExecReload = "${pkgs.coreutils}/bin/kill -USR1 $MAINPID"; ExecReload =
if isCaddy2 then
"${cfg.package}/bin/caddy reload --config ${configJSON}"
else
"${pkgs.coreutils}/bin/kill -USR1 $MAINPID";
Type = "simple"; Type = "simple";
User = "caddy"; User = "caddy";
Group = "caddy"; Group = "caddy";

View File

@ -1,7 +1,7 @@
import ./make-test-python.nix ({ pkgs, ... }: { import ./make-test-python.nix ({ pkgs, ... }: {
name = "caddy"; name = "caddy";
meta = with pkgs.stdenv.lib.maintainers; { meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ xfix ]; maintainers = [ xfix filalex77 ];
}; };
nodes = { nodes = {
@ -9,9 +9,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
services.caddy.enable = true; services.caddy.enable = true;
services.caddy.config = '' services.caddy.config = ''
http://localhost { http://localhost {
gzip encode gzip
root ${ file_server
root * ${
pkgs.runCommand "testdir" {} '' pkgs.runCommand "testdir" {} ''
mkdir "$out" mkdir "$out"
echo hello world > "$out/example.html" echo hello world > "$out/example.html"
@ -23,9 +24,10 @@ import ./make-test-python.nix ({ pkgs, ... }: {
specialisation.etag.configuration = { specialisation.etag.configuration = {
services.caddy.config = lib.mkForce '' services.caddy.config = lib.mkForce ''
http://localhost { http://localhost {
gzip encode gzip
root ${ file_server
root * ${
pkgs.runCommand "testdir2" {} '' pkgs.runCommand "testdir2" {} ''
mkdir "$out" mkdir "$out"
echo changed > "$out/example.html" echo changed > "$out/example.html"
@ -59,9 +61,11 @@ import ./make-test-python.nix ({ pkgs, ... }: {
) )
etag = etag.replace("\r\n", " ") etag = etag.replace("\r\n", " ")
http_code = webserver.succeed( http_code = webserver.succeed(
"curl -w \"%{{http_code}}\" -X HEAD -H 'If-None-Match: {}' {}".format(etag, url) "curl --silent --show-error -o /dev/null -w \"%{{http_code}}\" --head -H 'If-None-Match: {}' {}".format(
etag, url
)
) )
assert int(http_code) == 304, "HTTP code is not 304" assert int(http_code) == 304, "HTTP code is {}, expected 304".format(http_code)
return etag return etag

View File

@ -2,35 +2,23 @@
buildGoModule rec { buildGoModule rec {
pname = "caddy"; pname = "caddy";
version = "1.0.5"; version = "2.1.1";
subPackages = [ "caddy" ]; subPackages = [ "cmd/caddy" ];
src = fetchFromGitHub { src = fetchFromGitHub {
owner = "caddyserver"; owner = "caddyserver";
repo = pname; repo = pname;
rev = "v${version}"; rev = "v${version}";
sha256 = "0jrhwmr6gggppskg5h450wybzkv17iq69dgw36hd1dp56q002i7g"; sha256 = "0c682zrivkawsxlps5hlx8js5zp4ddahg0zi5cr0861gnllbdll0";
}; };
vendorSha256 = "09vnci9pp8zp7bvn8zj68wslz2nc54nhcd0ll31sqfjbp00215mj";
doCheck = false; vendorSha256 = "0jzx00c2b8y7zwl73r2fh1826spcd15y39nfzr53s5lay3fvkybc";
preBuild = ''
cat << EOF > caddy/main.go
package main
import "github.com/caddyserver/caddy/caddy/caddymain"
func main() {
caddymain.EnableTelemetry = false
caddymain.Run()
}
EOF
'';
meta = with stdenv.lib; { meta = with stdenv.lib; {
homepage = "https://caddyserver.com"; homepage = "https://caddyserver.com";
description = "Fast, cross-platform HTTP/2 web server with automatic HTTPS"; description = "Fast, cross-platform HTTP/2 web server with automatic HTTPS";
license = licenses.asl20; license = licenses.asl20;
maintainers = with maintainers; [ rushmorem fpletz zimbatm filalex77 ]; maintainers = with maintainers; [ filalex77 ];
}; };
} }

37
pkgs/servers/caddy/v1.nix Normal file
View File

@ -0,0 +1,37 @@
{ stdenv, buildGoModule, fetchFromGitHub }:
buildGoModule rec {
pname = "caddy";
version = "1.0.5";
goPackagePath = "github.com/caddyserver/caddy";
subPackages = [ "caddy" ];
src = fetchFromGitHub {
owner = "caddyserver";
repo = pname;
rev = "v${version}";
sha256 = "0jrhwmr6gggppskg5h450wybzkv17iq69dgw36hd1dp56q002i7g";
};
vendorSha256 = "09vnci9pp8zp7bvn8zj68wslz2nc54nhcd0ll31sqfjbp00215mj";
preBuild = ''
cat << EOF > caddy/main.go
package main
import "github.com/caddyserver/caddy/caddy/caddymain"
func main() {
caddymain.EnableTelemetry = false
caddymain.Run()
}
EOF
'';
meta = with stdenv.lib; {
homepage = "https://caddyserver.com";
description = "Fast, cross-platform HTTP/2 web server with automatic HTTPS";
license = licenses.asl20;
maintainers = with maintainers; [ rushmorem fpletz zimbatm filalex77 ];
};
}

View File

@ -1,26 +0,0 @@
{ stdenv, buildGoModule, fetchFromGitHub }:
buildGoModule rec {
pname = "caddy";
version = "2.1.1";
subPackages = [ "cmd/caddy" ];
src = fetchFromGitHub {
owner = "caddyserver";
repo = pname;
rev = "v${version}";
sha256 = "0c682zrivkawsxlps5hlx8js5zp4ddahg0zi5cr0861gnllbdll0";
};
vendorSha256 = "0jzx00c2b8y7zwl73r2fh1826spcd15y39nfzr53s5lay3fvkybc";
doCheck = false;
meta = with stdenv.lib; {
homepage = "https://caddyserver.com";
description = "Fast, cross-platform HTTP/2 web server with automatic HTTPS";
license = licenses.asl20;
maintainers = with maintainers; [ filalex77 ];
};
}

View File

@ -1509,12 +1509,8 @@ in
''; '';
}); });
caddy = callPackage ../servers/caddy { caddy = callPackage ../servers/caddy { buildGoModule = buildGo114Module; }; # https://github.com/lucas-clemente/quic-go/issues/2614
buildGoModule = buildGo114Module; caddy1 = callPackage ../servers/caddy/v1.nix { buildGoModule = buildGo114Module; };
};
caddy2 = callPackage ../servers/caddy/v2.nix {
buildGoModule = buildGo114Module;
};
traefik = callPackage ../servers/traefik { }; traefik = callPackage ../servers/traefik { };
calamares = libsForQt514.callPackage ../tools/misc/calamares { calamares = libsForQt514.callPackage ../tools/misc/calamares {