{
  config,
  utils,
  lib,
  globals,
  ...
}: {
  options.radicale.enable = lib.mkEnableOption "radicale";

  config = lib.mkIf config.radicale.enable {
    kubernetes.resources = {
      deployments.server.spec = {
        selector.matchLabels.app = "radicale";

        strategy = {
          type = "RollingUpdate";

          rollingUpdate = {
            maxSurge = 0;
            maxUnavailable = 1;
          };
        };

        template = {
          metadata.labels.app = "radicale";

          spec = {
            containers.radicale = {
              image = utils.mkNixNGImage "radicale";
              ports.web.containerPort = 5232;
              imagePullPolicy = "IfNotPresent";

              volumeMounts = [
                {
                  name = "data";
                  mountPath = "/data";
                }
              ];
            };

            volumes.data.persistentVolumeClaim.claimName = "data";
          };
        };
      };

      services.server.spec = {
        type = "LoadBalancer";
        loadBalancerIP = globals.radicaleIPv4;
        selector.app = "radicale";

        ports.web = {
          port = 80;
          targetPort = "web";
        };
      };
    };

    lab = {
      tailscaleIngresses.tailscale = {
        host = "radicale";
        service.name = "server";
      };

      longhorn.persistentVolumeClaim.data = {
        volumeName = "radicale";
        storage = "200Mi";
      };
    };
  };
}