1 { config, lib, pkgs, ... }:
3 cfg = config.services.soft-serve;
4 configFile = format.generate "config.yaml" cfg.settings;
5 format = pkgs.formats.yaml { };
6 docUrl = "https://charm.sh/blog/self-hosted-soft-serve/";
7 stateDir = "/var/lib/soft-serve";
11 services.soft-serve = {
12 enable = lib.mkEnableOption "soft-serve";
14 package = lib.mkPackageOption pkgs "soft-serve" { };
16 settings = lib.mkOption {
20 The contents of the configuration file for soft-serve.
24 example = lib.literalExpression ''
26 name = "dadada's repos";
29 listen_addr = ":23231";
30 public_url = "ssh://localhost:23231";
34 stats.listen_addr = ":23233";
41 config = lib.mkIf cfg.enable {
43 systemd.tmpfiles.rules = [
44 # The config file has to be inside the state dir
45 "L+ ${stateDir}/config.yaml - - - - ${configFile}"
48 systemd.services.soft-serve = {
49 description = "Soft Serve git server";
50 documentation = [ docUrl ];
51 requires = [ "network-online.target" ];
52 after = [ "network-online.target" ];
53 wantedBy = [ "multi-user.target" ];
55 environment.SOFT_SERVE_DATA_PATH = stateDir;
61 ExecStart = "${lib.getExe cfg.package} serve";
62 StateDirectory = "soft-serve";
63 WorkingDirectory = stateDir;
64 RuntimeDirectory = "soft-serve";
65 RuntimeDirectoryMode = "0750";
67 ProtectProc = "invisible";
69 CapabilityBoundingSet = "";
71 PrivateDevices = true;
73 ProtectHostname = true;
75 ProtectKernelTunables = true;
76 ProtectKernelModules = true;
77 ProtectKernelLogs = true;
78 ProtectControlGroups = true;
79 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
80 RestrictNamespaces = true;
81 LockPersonality = true;
82 MemoryDenyWriteExecute = true;
83 RestrictRealtime = true;
86 SystemCallArchitectures = "native";
89 "~@cpu-emulation @debug @keyring @module @mount @obsolete @privileged @raw-io @reboot @setuid @swap"
95 meta.maintainers = [ lib.maintainers.dadada ];