1 { config, lib, pkgs, ... }:
6 cfg = config.services.soft-serve;
7 configFile = format.generate "config.yaml" cfg.settings;
8 format = pkgs.formats.yaml { };
9 docUrl = "https://charm.sh/blog/self-hosted-soft-serve/";
10 stateDir = "/var/lib/soft-serve";
14 services.soft-serve = {
15 enable = mkEnableOption "soft-serve";
17 package = mkPackageOption pkgs "soft-serve" { };
23 The contents of the configuration file for soft-serve.
27 example = literalExpression ''
29 name = "dadada's repos";
32 listen_addr = ":23231";
33 public_url = "ssh://localhost:23231";
37 stats.listen_addr = ":23233";
44 config = mkIf cfg.enable {
46 systemd.tmpfiles.rules = [
47 # The config file has to be inside the state dir
48 "L+ ${stateDir}/config.yaml - - - - ${configFile}"
51 systemd.services.soft-serve = {
52 description = "Soft Serve git server";
53 documentation = [ docUrl ];
54 requires = [ "network-online.target" ];
55 after = [ "network-online.target" ];
56 wantedBy = [ "multi-user.target" ];
58 environment.SOFT_SERVE_DATA_PATH = stateDir;
64 ExecStart = "${getExe cfg.package} serve";
65 StateDirectory = "soft-serve";
66 WorkingDirectory = stateDir;
67 RuntimeDirectory = "soft-serve";
68 RuntimeDirectoryMode = "0750";
70 ProtectProc = "invisible";
72 CapabilityBoundingSet = "";
74 PrivateDevices = true;
76 ProtectHostname = true;
78 ProtectKernelTunables = true;
79 ProtectKernelModules = true;
80 ProtectKernelLogs = true;
81 ProtectControlGroups = true;
82 RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
83 RestrictNamespaces = true;
84 LockPersonality = true;
85 MemoryDenyWriteExecute = true;
86 RestrictRealtime = true;
89 SystemCallArchitectures = "native";
92 "~@cpu-emulation @debug @keyring @module @mount @obsolete @privileged @raw-io @reboot @setuid @swap"
98 meta.maintainers = [ maintainers.dadada ];