feat: add a Caddy reverse-proxy option to the NixOS module

This commit is contained in:
randogoth 2026-09-26 20:11:58 +03:00
parent 4075afbb11
commit a244dab94e
2 changed files with 47 additions and 3 deletions

View file

@ -72,8 +72,9 @@ in
Address the bridge listens on. The bridge speaks plain HTTP/WS with no
TLS of its own, and browsers refuse a `ws://` connection from an
`https://` page — so leave this at loopback and put a reverse proxy
(see `services.gsmol-bridge.nginx`) in front for TLS and public
exposure, rather than binding this directly to a public interface.
(`services.gsmol-bridge.nginx` or `.caddy`) in front for TLS and
public exposure, rather than binding this directly to a public
interface.
'';
};
@ -123,10 +124,42 @@ in
description = "Public hostname to serve gsmol from.";
};
};
caddy = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Put a Caddy virtual host in front of the bridge, with automatic
HTTPS — no `enableACME`/`forceSSL` to set, Caddy does this itself
for any site address that isn't `http://`-prefixed.
This wires into the standard `services.caddy.virtualHosts` option
and has no effect if your own configuration replaces
`services.caddy.configFile` outright with a hand-written Caddyfile
— that style of deployment needs the domain added to that file
instead (e.g. an imported drop-in), proxying to
`services.gsmol-bridge.host`:`.port`.
'';
};
domain = lib.mkOption {
type = lib.types.str;
example = "mail.example.org";
description = "Public hostname to serve gsmol from.";
};
};
};
config = lib.mkIf cfg.enable (lib.mkMerge [
{
assertions = [
{
assertion = !(cfg.nginx.enable && cfg.caddy.enable);
message = "services.gsmol-bridge: enable only one of .nginx or .caddy";
}
];
systemd.services.gsmol-bridge = {
description = "gsmol web client and Smol Mail bridge";
wantedBy = [ "multi-user.target" ];
@ -186,5 +219,16 @@ in
};
};
})
(lib.mkIf cfg.caddy.enable {
services.caddy.enable = true;
# No proxyWebsockets-style flag needed: Caddy's reverse_proxy upgrades a
# WebSocket connection transparently, and it self-provisions TLS for a
# non-http:// site address, so neither forceSSL nor enableACME has a
# caddy-side equivalent to set here.
services.caddy.virtualHosts.${cfg.caddy.domain}.extraConfig = ''
reverse_proxy ${cfg.host}:${toString cfg.port}
'';
})
]);
}