Caddy: Difference between revisions
imported>Malteneuss Simplify curl check and add explanation for https |
Added instructions to build Caddy with plugins. |
||
(16 intermediate revisions by 9 users not shown) | |||
Line 2: | Line 2: | ||
It can also be a reverse proxy to serve multiple web services under one server. Its main features are its simple config setup and automatic HTTPS: It will automatically request and renew a LetsEncrypt certificate so that users of your service get a Browser-trusted and secure connection. | It can also be a reverse proxy to serve multiple web services under one server. Its main features are its simple config setup and automatic HTTPS: It will automatically request and renew a LetsEncrypt certificate so that users of your service get a Browser-trusted and secure connection. | ||
== | == Setup == | ||
To try out Caddy add the following minimal example to your NixOS module: | To try out Caddy add the following minimal example to your [[NixOS modules | NixOS module]]: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
services.caddy = { | { | ||
# ... | |||
services.caddy = { | |||
enable = true; | |||
virtualHosts."localhost".extraConfig = '' | |||
}; | respond "Hello, world!" | ||
''; | |||
}; | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 47: | Line 50: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Curl will set <code>Host</code> header and TLS <code>SNI</> in the request to <code><virtualhost></code> as desired by Caddy, but will make the actual request against the <code><realhost></code>, e.g. a load-balancer or ingress-controller. | Curl will set <code>Host</code> header and TLS <code>SNI</code> in the request to <code><virtualhost></code> as desired by Caddy, but will make the actual request against the <code><realhost></code>, e.g. a load-balancer or ingress-controller. | ||
Alternatively with http and automatic redirects to https you can extend that call: | Alternatively with http and automatic redirects to https you can extend that call: | ||
Line 92: | Line 95: | ||
virtualHosts."example.org".extraConfig = '' | virtualHosts."example.org".extraConfig = '' | ||
reverse_proxy http://10.25.40.6 | reverse_proxy http://10.25.40.6 | ||
''; | |||
virtualHosts."another.example.org".extraConfig = '' | |||
reverse_proxy unix//run/gunicorn.sock | |||
''; | ''; | ||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight>In case you would like to forward the real client IP of the request to the backend, add following headers<syntaxhighlight lang="nix"> | ||
services.caddy = { | |||
virtualHosts."example.org".extraConfig = '' | |||
reverse_proxy http://10.25.40.6 { | |||
header_down X-Real-IP {http.request.remote} | |||
header_down X-Forwarded-For {http.request.remote} | |||
} | |||
''; | |||
}; | |||
</syntaxhighlight>Fur further reverse proxy configuration, see [https://caddyserver.com/docs/quick-starts/reverse-proxy upstream documentation]. | |||
=== Redirect === | === Redirect === | ||
Permanent redirect of <code>example.org</code> and <code>old.example.org</code> to <code>www.example.org</code> | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
Line 107: | Line 120: | ||
virtualHosts."example.org" = { | virtualHosts."example.org" = { | ||
extraConfig = '' | extraConfig = '' | ||
redir https://www.example.org | redir https://www.example.org{uri} permanent | ||
''; | ''; | ||
serverAliases = [ "old.example.org" ]; | |||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 131: | Line 144: | ||
You'll need a [[Phpfpm|PHP-FPM]] socket listening on Unix socket path <code>/var/run/phpfpm/localhost.sock</code>. | You'll need a [[Phpfpm|PHP-FPM]] socket listening on Unix socket path <code>/var/run/phpfpm/localhost.sock</code>. | ||
=== Passing environment variable secrets/configuring acme_dns === | |||
To prevent any secrets from being put in the nix store (any NixOS setting that writes a config in the Nix store will expose any secret in it), you can use the following setting<syntaxhighlight lang="nixos"> | |||
services.caddy = { | |||
enable = true; | |||
globalConfig = '' | |||
acme_dns PROVIDER { | |||
api_key {$APIKEY} | |||
api_secret_key {$APISECRETKEY} | |||
} | |||
''; | |||
}; | |||
systemd.services.caddy.serviceConfig.EnvironmentFile = ["/path/to/envfile"]; | |||
</syntaxhighlight>And then at '''/path/to/envfile''':<syntaxhighlight> | |||
APIKEY=YOURKEY | |||
APISECRETKEY=OTHERKEY | |||
</syntaxhighlight> | |||
=== Adding plug-ins === | |||
There are many Issues/PR's about allowing Caddy to be built with plug-ins. Until then, you can use this workaround:<syntaxhighlight lang="nixos"> | |||
services.caddy = { | |||
enable = true; | |||
package = (pkgs.callPackage "${builtins.fetchurl https://raw.githubusercontent.com/jpds/nixpkgs/a33b02fa9d664f31dadc8a874eb1a5dbaa9f4ecf/pkgs/servers/caddy/default.nix}" { | |||
externalPlugins = [ | |||
{ name = "caddy-dns/porkbun"; repo = "github.com/caddy-dns/porkbun"; version = "4267f6797bf6543d7b20cdc8578a31764face4cf"; } | |||
# Set version to target repository commit hash | |||
]; | |||
vendorHash = ""; # Add this as explained in https://github.com/NixOS/nixpkgs/pull/259275#issuecomment-1763478985 | |||
}); | |||
globalConfig = '' | |||
... | |||
''; | |||
} | |||
</syntaxhighlight> | |||
== Debugging == | == Debugging == | ||
Line 192: | Line 239: | ||
* [https://caddyserver.com/docs/caddyfile/directives/tls Caddy TLS settings documentation] | * [https://caddyserver.com/docs/caddyfile/directives/tls Caddy TLS settings documentation] | ||
== Adding Plugins == | |||
Caddy supports being extended with plugins, which must be added during the build process<ref>https://github.com/caddyserver/caddy?tab=readme-ov-file#with-version-information-andor-plugins</ref>. The simplest option to do this in Nix is by using an override to build a customized version of Caddy. | |||
Follow the instructions for [https://github.com/caddyserver/caddy?tab=readme-ov-file#with-version-information-andor-plugins setting up Caddy to build with plugins], either by using xcaddy, or following the manual steps. In your configuration, override Caddy to build using this local Go module. If you created the main.go file in the same location as your caddy Nix config, it can look something like this: | |||
<syntaxhighlight lang="nix"> | |||
services.caddy.package = pkgs.caddy.overrideAttrs ( | |||
self: super: { | |||
src = ./.; | |||
vendorHash = ""; | |||
subPackages = [ ]; | |||
} | |||
); | |||
</syntaxhighlight> | |||
== See also == | == See also == | ||
Line 200: | Line 261: | ||
[[Category:Applications]] | [[Category:Applications]] | ||
[[Category: | [[Category:Server]] | ||
[[Category:Networking]] |