flake: { config, lib, pkgs, ... }: let cfg = config.services.witryna; in { options.services.witryna = { enable = lib.mkEnableOption "witryna deployment service"; package = lib.mkOption { type = lib.types.package; default = flake.packages.${pkgs.stdenv.hostPlatform.system}.witryna; description = "The witryna package to use."; }; configFile = lib.mkOption { type = lib.types.path; description = "Path to witryna.toml configuration file."; }; }; config = lib.mkIf cfg.enable { users.users.witryna = { isSystemUser = true; group = "witryna"; home = "/var/lib/witryna"; }; users.groups.witryna = {}; systemd.tmpfiles.rules = [ "d /var/lib/witryna 0755 witryna witryna -" "d /var/lib/witryna/clones 0755 witryna witryna -" "d /var/lib/witryna/builds 0755 witryna witryna -" "d /var/lib/witryna/cache 0755 witryna witryna -" "d /var/log/witryna 0755 witryna witryna -" ]; systemd.services.witryna = { description = "Witryna - Git-based static site deployment orchestrator"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; User = "witryna"; Group = "witryna"; ExecStart = "${cfg.package}/bin/witryna serve --config ${cfg.configFile}"; ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; Restart = "on-failure"; RestartSec = 5; # Security hardening (mirrors debian/witryna.service) NoNewPrivileges = true; PrivateTmp = true; ProtectSystem = "strict"; ProtectKernelTunables = true; ProtectKernelModules = true; ProtectControlGroups = true; RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; LockPersonality = true; MemoryDenyWriteExecute = true; ReadWritePaths = [ "/var/lib/witryna" "/var/log/witryna" "/run/user" ]; LimitNOFILE = 65536; LimitNPROC = 4096; }; }; }; }