Caddy: Difference between revisions

From NixOS Wiki
imported>Malteneuss
No edit summary
imported>Malteneuss
Add debugging section
Line 5: Line 5:
The example snippet below will run Caddy on http://localhost and serving an [http://localhost/example.html example.html] page.
The example snippet below will run Caddy on http://localhost and serving an [http://localhost/example.html example.html] page.


<syntaxhighlight lang="nix>
<syntaxhighlight lang="nix">
services.caddy = {
services.caddy = {
   enable = true;
   enable = true;
Line 29: Line 29:
Caddy will automatically try to acquire SSL certificates for the specified domain, in this example <code>example.org</code>. This requires you to configure the DNS records of your domain correctly, which should point to the address of your Caddy server. The [[firewall]] ports <code>80</code> and <code>443</code> needs to be opened.
Caddy will automatically try to acquire SSL certificates for the specified domain, in this example <code>example.org</code>. This requires you to configure the DNS records of your domain correctly, which should point to the address of your Caddy server. The [[firewall]] ports <code>80</code> and <code>443</code> needs to be opened.


<syntaxhighlight lang="nix>
<syntaxhighlight lang="nix">
services.caddy = {
services.caddy = {
   enable = true;
   enable = true;
Line 49: Line 49:
The following snippet creates a reverse proxy for the domain <code>example.org</code>, redirecting all requests to <code><nowiki>http://10.25.40.6</nowiki></code>
The following snippet creates a reverse proxy for the domain <code>example.org</code>, redirecting all requests to <code><nowiki>http://10.25.40.6</nowiki></code>


<syntaxhighlight lang="nix>
<syntaxhighlight lang="nix">
services.caddy = {
services.caddy = {
   enable = true;
   enable = true;
Line 57: Line 57:
};
};
</syntaxhighlight>
</syntaxhighlight>
* [https://caddyserver.com/docs/quick-starts/reverse-proxy Caddy reverse proxy documentation]


=== Redirect ===
=== Redirect ===
Line 62: Line 64:
Redirecting <code>example.org</code> and <code>old.example.org</code> to <code>www.example.org</code>
Redirecting <code>example.org</code> and <code>old.example.org</code> to <code>www.example.org</code>


<syntaxhighlight lang="nix>
<syntaxhighlight lang="nix">
services.caddy = {
services.caddy = {
   enable = true;
   enable = true;
Line 77: Line 79:
Serving a PHP application in <code>/var/www</code> on http://localhost .
Serving a PHP application in <code>/var/www</code> on http://localhost .


<syntaxhighlight lang="nix>
<syntaxhighlight lang="nix">
services.caddy = {
services.caddy = {
   enable = true;
   enable = true;
Line 91: Line 93:


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>.
== Debugging ==
To check if Caddy is running and listening as configured you can run netstat:
<syntaxhighlight lang="bash">
$ netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q  Local Address      Foreign Address        State      PID/Program name   
tcp        0              0        127.0.0.1:2019          0.0.0.0:*              LISTEN      1202/caddy         
tcp6      0              0          :::80                              :::*                  LISTEN      1202/caddy         
tcp6      0              0          :::443                            :::*                  LISTEN      1202/caddy         
udp6    0              0          :::443                            :::*                                    1202/caddy         
</syntaxhighlight>
The tcp (ipv4) socket port 2019 is Caddy's management endpoint, for when you want manage its config via web REST calls instead of Nix (ignore).
The tcp6 (an ipv6 socket that also listens on ipv4) socket on port 80 (HTTP) and 443 (HTTPS) indicate that a virtualhost config was used.
You can also use curl to test http(s) calls. However, you must set the "Host" header correctly when testing locally:
<syntaxhighlight lang="bash">
$ curl localhost -H "Host: example.org"
</syntaxhighlight>
for an virtualhost config like
<syntaxhighlight lang="nix">
services.caddy = {
  enable = true;
  virtualHosts."example.org".extraConfig = ''
    respond "Hello, world!"
  '';
};
</syntaxhighlight>
If the response is empty, try setting a port number like 80 and/or try a local TLS security certificate instead of global LetsEncrypt:
<syntaxhighlight lang="nix">
services.caddy = {
  enable = true;
  virtualHosts."example.org:80".extraConfig = ''
    respond "Hello, world!"
    tls internal
  '';
};
</syntaxhighlight>
With "tls internal" Caddy will generate a local certificate, which is good when testing locally and/or you don't have internet access (e.g. inside a nixos-container).
* [https://caddyserver.com/docs/caddyfile/directives/tls Caddy TLS settings documentation]


== See also ==
== See also ==

Revision as of 09:01, 8 July 2023

Caddy is a HTTP/2 capable web server with automatic HTTPS.

Installation

The example snippet below will run Caddy on http://localhost and serving an example.html page.

services.caddy = {
  enable = true;
  extraConfig = ''
    http://localhost {
      encode gzip
      file_server
      root * ${
        pkgs.runCommand "testdir" {} ''
          mkdir "$out"
          echo hello world > "$out/example.html"
        ''
      }
    }
  '';
};

Configuration examples

SSL

Caddy will automatically try to acquire SSL certificates for the specified domain, in this example example.org. This requires you to configure the DNS records of your domain correctly, which should point to the address of your Caddy server. The firewall ports 80 and 443 needs to be opened.

services.caddy = {
  enable = true;
  virtualHosts."example.org".extraConfig = ''
    encode gzip
    file_server
    root * ${
      pkgs.runCommand "testdir" {} ''
        mkdir "$out"
        echo hello world > "$out/example.html"
      ''
    }
  '';
};

Reverse proxy

The following snippet creates a reverse proxy for the domain example.org, redirecting all requests to http://10.25.40.6

services.caddy = {
  enable = true;
  virtualHosts."example.org".extraConfig = ''
    reverse_proxy http://10.25.40.6
  '';
};

Redirect

Redirecting example.org and old.example.org to www.example.org

services.caddy = {
  enable = true;
  virtualHosts."example.org" = {
    extraConfig = ''
      redir https://www.example.org
   '';
    serverAlias = [ "old.example.org" ];
};

PHP FastCGI

Serving a PHP application in /var/www on http://localhost .

services.caddy = {
  enable = true;
  virtualHosts."http://localhost" = {
    extraConfig = ''
      root    * /var/www
      file_server
      php_fastcgi unix/var/run/phpfpm/localhost.sock
    '';
  };
};

You'll need a PHP-FPM socket listening on Unix socket path /var/run/phpfpm/localhost.sock.

Debugging

To check if Caddy is running and listening as configured you can run netstat:

$ netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q  Local Address      Foreign Address         State       PID/Program name    
tcp        0              0        127.0.0.1:2019          0.0.0.0:*               LISTEN      1202/caddy          
tcp6      0              0          :::80                               :::*                  LISTEN      1202/caddy          
tcp6      0              0          :::443                             :::*                  LISTEN      1202/caddy          
udp6     0              0          :::443                             :::*                                    1202/caddy

The tcp (ipv4) socket port 2019 is Caddy's management endpoint, for when you want manage its config via web REST calls instead of Nix (ignore). The tcp6 (an ipv6 socket that also listens on ipv4) socket on port 80 (HTTP) and 443 (HTTPS) indicate that a virtualhost config was used.

You can also use curl to test http(s) calls. However, you must set the "Host" header correctly when testing locally:

$ curl localhost -H "Host: example.org"

for an virtualhost config like

services.caddy = {
  enable = true;
  virtualHosts."example.org".extraConfig = ''
    respond "Hello, world!"
  '';
};

If the response is empty, try setting a port number like 80 and/or try a local TLS security certificate instead of global LetsEncrypt:

services.caddy = {
  enable = true;
  virtualHosts."example.org:80".extraConfig = ''
    respond "Hello, world!"
    tls internal
  '';
};

With "tls internal" Caddy will generate a local certificate, which is good when testing locally and/or you don't have internet access (e.g. inside a nixos-container).

See also