1 { config, pkgs, lib, ... }:
5 cfg = config.services.sourcehut;
7 settingsFormat = pkgs.formats.ini { };
9 # Specialized python containing all the modules
10 python = pkgs.sourcehut.python.withPackages (ps: with ps; [
40 (mkRemovedOptionModule [ "services" "sourcehut" "nginx" "enable" ] ''
41 The sourcehut module supports `nginx` as a local reverse-proxy by default and doesn't
42 support other reverse-proxies officially.
44 However it's possible to use an alternative reverse-proxy by
47 * adjusting the relevant settings for server addresses and ports directly
49 Further details about this can be found in the `Sourcehut`-section of the NixOS-manual.
53 options.services.sourcehut = {
54 enable = mkEnableOption ''
55 sourcehut - git hosting, continuous integration, mailing list, ticket tracking,
56 task dispatching, wiki and account management services
60 type = types.nonEmptyListOf (types.enum [ "builds" "dispatch" "git" "hub" "hg" "lists" "man" "meta" "paste" "todo" ]);
61 default = [ "man" "meta" "paste" ];
62 example = [ "builds" "dispatch" "git" "hub" "hg" "lists" "man" "meta" "paste" "todo" ];
64 Services to enable on the sourcehut network.
68 originBase = mkOption {
70 default = with config.networking; hostName + lib.optionalString (domain != null) ".${domain}";
72 Host name used by reverse-proxy and for default settings. Will host services at git."''${originBase}". For example: git.sr.ht
78 default = "127.0.0.1";
89 The python package to use. It should contain references to the *srht modules and also
94 statePath = mkOption {
96 default = "/var/lib/sourcehut";
98 Root state path for the sourcehut network. If left as the default value
99 this directory will automatically be created before the sourcehut server
100 starts, otherwise the sysadmin is responsible for ensuring the
101 directory exists with appropriate ownership and permissions.
105 settings = mkOption {
106 type = lib.types.submodule {
107 freeformType = settingsFormat.type;
108 options."builds.sr.ht" = {
109 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
111 options."dispatch.sr.ht" = {
112 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
114 options."git.sr.ht" = {
115 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
117 options."hg.sr.ht" = {
118 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
120 options."hub.sr.ht" = {
121 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
123 options."lists.sr.ht" = {
124 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
126 options."man.sr.ht" = {
127 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
129 options."meta.sr.ht" = {
130 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
132 options."paste.sr.ht" = {
133 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
135 options."todo.sr.ht" = {
136 migrate-on-upgrade = mkEnableOption "automatically run migrations on package upgrade";
141 The configuration for the sourcehut network.
146 config = mkIf cfg.enable {
150 assertion = with cfgIni.webhooks; private-key != null && stringLength private-key == 44;
151 message = "The webhook's private key must be defined and of a 44 byte length.";
155 assertion = hasAttrByPath [ "meta.sr.ht" "origin" ] cfgIni && cfgIni."meta.sr.ht".origin != null;
156 message = "meta.sr.ht's origin must be defined.";
160 environment.etc."sr.ht/config.ini".source =
161 settingsFormat.generate "sourcehut-config.ini" (mapAttrsRecursive
163 path: v: if v == null then "" else v
167 environment.systemPackages = [ pkgs.sourcehut.coresrht ];
170 services.postgresql.enable = mkOverride 999 true;
172 services.postfix.enable = mkOverride 999 true;
174 services.cron.enable = mkOverride 999 true;
176 services.redis.enable = mkOverride 999 true;
177 services.redis.bind = mkOverride 999 "127.0.0.1";
179 services.sourcehut.settings = {
180 # The name of your network of sr.ht-based sites
181 "sr.ht".site-name = mkDefault "sourcehut";
182 # The top-level info page for your site
183 "sr.ht".site-info = mkDefault "https://sourcehut.org";
184 # {{ site-name }}, {{ site-blurb }}
185 "sr.ht".site-blurb = mkDefault "the hacker's forge";
186 # If this != production, we add a banner to each page
187 "sr.ht".environment = mkDefault "development";
188 # Contact information for the site owners
189 "sr.ht".owner-name = mkDefault "Drew DeVault";
190 "sr.ht".owner-email = mkDefault "sir@cmpwn.com";
191 # The source code for your fork of sr.ht
192 "sr.ht".source-url = mkDefault "https://git.sr.ht/~sircmpwn/srht";
193 # A secret key to encrypt session cookies with
194 "sr.ht".secret-key = mkDefault null;
195 "sr.ht".global-domain = mkDefault null;
197 # Outgoing SMTP settings
198 mail.smtp-host = mkDefault null;
199 mail.smtp-port = mkDefault null;
200 mail.smtp-user = mkDefault null;
201 mail.smtp-password = mkDefault null;
202 mail.smtp-from = mkDefault null;
203 # Application exceptions are emailed to this address
204 mail.error-to = mkDefault null;
205 mail.error-from = mkDefault null;
206 # Your PGP key information (DO NOT mix up pub and priv here)
207 # You must remove the password from your secret key, if present.
208 # You can do this with gpg --edit-key [key-id], then use the passwd
209 # command and do not enter a new password.
210 mail.pgp-privkey = mkDefault null;
211 mail.pgp-pubkey = mkDefault null;
212 mail.pgp-key-id = mkDefault null;
214 # base64-encoded Ed25519 key for signing webhook payloads. This should be
215 # consistent for all *.sr.ht sites, as we'll use this key to verify signatures
216 # from other sites in your network.
218 # Use the srht-webhook-keygen command to generate a key.
219 webhooks.private-key = mkDefault null;
222 meta.doc = ./sourcehut.xml;
223 meta.maintainers = with maintainers; [ tomberek ];