initial commit
All checks were successful
Deploy docs / build-and-deploy (push) Successful in 3s

This commit is contained in:
sid 2026-02-23 20:34:35 +01:00
commit 95a533c876
451 changed files with 18255 additions and 0 deletions

View file

@ -0,0 +1,116 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.radicale;
domain = config.networking.domain;
subdomain = cfg.reverseProxy.subdomain;
fqdn = if (cfg.reverseProxy.enable && subdomain != "") then "${subdomain}.${domain}" else domain;
port = 5232;
inherit (lib)
concatLines
mkDefault
mkIf
mkOption
types
;
inherit (lib.utils)
mkReverseProxyOption
;
in
{
options.services.radicale = {
users = mkOption {
type = types.listOf types.str;
default = [ ];
example = [
"alice"
"bob"
];
description = "List of users for Radicale. Each user must have a corresponding entry in the SOPS file under 'radicale/<user>'";
};
reverseProxy = mkReverseProxyOption "Radicale" "dav";
};
config = mkIf cfg.enable {
services.radicale = {
settings = {
server = {
hosts = [
"${if cfg.reverseProxy.enable then "127.0.0.1" else "0.0.0.0"}:${builtins.toString port}"
];
max_connections = mkDefault 20;
max_content_length = mkDefault 500000000;
timeout = mkDefault 30;
};
auth = {
type = "htpasswd";
delay = mkDefault 1;
htpasswd_filename = config.sops.templates."radicale/users".path;
htpasswd_encryption = mkDefault "sha512";
};
storage = {
filesystem_folder = mkDefault "/var/lib/radicale/collections";
};
};
};
services.nginx.virtualHosts = mkIf cfg.reverseProxy.enable {
"${fqdn}" = {
forceSSL = cfg.reverseProxy.forceSSL;
enableACME = cfg.reverseProxy.forceSSL;
locations = {
"/" = {
proxyPass = "http://localhost:${builtins.toString port}/";
extraConfig = ''
proxy_set_header X-Script-Name /;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header Authorization;
'';
};
"/.well-known/caldav" = {
return = "301 $scheme://$host/";
};
"/.well-known/carddav" = {
return = "301 $scheme://$host/";
};
};
};
};
environment.systemPackages = [
pkgs.openssl
];
sops =
let
owner = "radicale";
group = "radicale";
mode = "0440";
mkSecrets =
users:
builtins.listToAttrs (
map (user: {
name = "radicale/${user}";
value = { inherit owner group mode; };
}) users
);
mkTemplate = users: {
inherit owner group mode;
content = concatLines (map (user: "${user}:${config.sops.placeholder."radicale/${user}"}") users);
};
in
{
secrets = mkSecrets cfg.users;
templates."radicale/users" = mkTemplate cfg.users;
};
};
}