Caddy: Difference between revisions

Onny (talk | contribs)
Plug-ins: Instruction use plugins without version tag
Andrew (talk | contribs)
Check used ports: Replace deprecated netstat with ss
 
(5 intermediate revisions by 3 users not shown)
Line 14: Line 14:


This snippet will let Caddy respond on <code>http://localhost</code> and <code>https://localhost</code> with a dummy text "Hello world!". When no port is mentioned on virtualhost like just <code>localhost</code> instead of <code>localhost:8080</code>, Caddy listens on <code>80</code> and <code>443</code> by default and redirects requests from port 80 (unsecured) to 443 (secured).
This snippet will let Caddy respond on <code>http://localhost</code> and <code>https://localhost</code> with a dummy text "Hello world!". When no port is mentioned on virtualhost like just <code>localhost</code> instead of <code>localhost:8080</code>, Caddy listens on <code>80</code> and <code>443</code> by default and redirects requests from port 80 (unsecured) to 443 (secured).
Use <code>curl -iLk localhost</code> to verify the configuration.


For SSL to work, just supply a public domain and ensure HTTP and HTTPS ports are accessible. Caddy will automatically configure TLS:
For SSL to work, just supply a public domain and ensure HTTP and HTTPS ports are accessible. Caddy will automatically configure TLS:
Line 27: Line 29:


== Configuration ==
== Configuration ==
=== Plug-ins ===
Following example is adding the plugin powerdns in version 1.0.1 to your Caddy binary
<syntaxhighlight lang="nix">
services.caddy = {
  enable = true;
  package = pkgs.caddy.withPlugins {
    plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" ];
    hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc=";
  };
};
</syntaxhighlight>
Get the correct hash by leaving the string empty at first and after rebuild, insert the hash which the build process calculated.
In case a plugin has no version tag, you'll have to query it first. In this example we'll do this for the plugin caddy-webdav
<syntaxhighlight lang="sh">
$ go mod init temp
$ go get github.com/mholt/caddy-webdav
$ grep 'caddy-webdav' go.mod
        github.com/mholt/caddy-webdav v0.0.0-20241008162340-42168ba04c9d // indirect
</syntaxhighlight>
Add this version string to your final config
<syntaxhighlight lang="nix">
services.caddy = {
  enable = true;
  package = pkgs.caddy.withPlugins {
    plugins = [ "github.com/caddy-dns/caddy-webdav@v0.0.0-20241008162340-42168ba04c9d" ];
    hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc=";
  };
};
</syntaxhighlight>


=== Reverse proxy ===
=== Reverse proxy ===
Line 124: Line 88:


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>.
=== Plug-ins ===
Following example is adding the plugin powerdns in version 1.0.1 to your Caddy binary
<syntaxhighlight lang="nix">
services.caddy = {
  enable = true;
  package = pkgs.caddy.withPlugins {
    plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" ];
    hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc=";
  };
};
</syntaxhighlight>
Get the correct hash by leaving the string empty at first and after rebuild, insert the hash which the build process calculated.
In case a plugin has no version tag, you'll have to query it first. In this example we'll do this for the plugin caddy-webdav
<syntaxhighlight lang="sh">
$ go mod init temp
$ go get github.com/mholt/caddy-webdav
$ grep 'caddy-webdav' go.mod
        github.com/mholt/caddy-webdav v0.0.0-20241008162340-42168ba04c9d // indirect
</syntaxhighlight>
Add this version string to your final config
<syntaxhighlight lang="nix">
services.caddy = {
  enable = true;
  package = pkgs.caddy.withPlugins {
    plugins = [ "github.com/caddy-dns/caddy-webdav@v0.0.0-20241008162340-42168ba04c9d" ];
    hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc=";
  };
};
</syntaxhighlight>
=== uWSGI apps ===
Serving uWSGI apps with Caddy also requires a plugin, in this example we'll use [https://github.com/wxh06/caddy-uwsgi-transport caddy-uwsgi-transport]. See section above on how to fetch and update plugins.<syntaxhighlight lang="nix">
services.caddy = {
  package = pkgs.caddy.withPlugins {
    plugins = [ "github.com/BadAimWeeb/caddy-uwsgi-transport@v0.0.0-20240317192154-74a1008b9763" ];
    hash = "sha256-aEdletYtVFnQMlWL6YW4gUgrrTBatoCIuugA/yvMGmI=";
  };
  virtualHosts = {
    "myapp.example.org" = {
      extraConfig = ''
        reverse_proxy unix/${config.services.uwsgi.runDir}/myapp.sock {
          transport uwsgi
        }
      '';
  };
};
</syntaxhighlight>This example will serve a [[uWSGI]] app, provided by a unix socket file, on the host <code>myapp.example.org</code>.


=== Passing environment variable secrets/configuring acme_dns ===
=== Passing environment variable secrets/configuring acme_dns ===
Line 145: Line 166:


=== Check used ports ===
=== Check used ports ===
To check if Caddy is running and listening as configured you can run <code>netstat</code>:
To check if Caddy is running and listening as configured you can run <code>ss</code>:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
$ netstat -tulpn
$ sudo ss --listening --no-queues --numeric --processes --tcp --udp | grep 'Process\|caddy'
Active Internet connections (only servers)
Netid State      Local Address:Port  Peer Address:Port Process
Proto Recv-Q Send-Q Local Address           Foreign Address         State      PID/Program name   
tcp   LISTEN          127.0.0.1:2019       0.0.0.0:*   users:(("caddy",pid=1000,fd=10))
tcp       0      0 127.0.0.1:2019         0.0.0.0:*               LISTEN      1202/caddy          
tcp  LISTEN                  *:80               *:*    users:(("caddy",pid=1000,fd=11))
tcp6      0      0 :::80                   :::*                    LISTEN      1202/caddy        
tcp  LISTEN                  *:443             *:*    users:(("caddy",pid=1000,fd=12))
tcp6      0      0 :::443                 :::*                    LISTEN      1202/caddy        
udp  UNCONN                  *:443             *:*    users:(("caddy",pid=1000,fd=13))
udp6      0      0 :::443                 :::*                                1202/caddy          
</syntaxhighlight>
</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 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).