grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / services / misc / gogs.nix
bloba2c1ad0779e15f81d1773e6ef6e036f3b59d469a
1 { config, lib, options, pkgs, ... }:
2 let
3   cfg = config.services.gogs;
4   opt = options.services.gogs;
5   configFile = pkgs.writeText "app.ini" ''
6     BRAND_NAME = ${cfg.appName}
7     RUN_USER = ${cfg.user}
8     RUN_MODE = prod
10     [database]
11     TYPE = ${cfg.database.type}
12     HOST = ${cfg.database.host}:${toString cfg.database.port}
13     NAME = ${cfg.database.name}
14     USER = ${cfg.database.user}
15     PASSWORD = #dbpass#
16     PATH = ${cfg.database.path}
18     [repository]
19     ROOT = ${cfg.repositoryRoot}
21     [server]
22     DOMAIN = ${cfg.domain}
23     HTTP_ADDR = ${cfg.httpAddress}
24     HTTP_PORT = ${toString cfg.httpPort}
25     EXTERNAL_URL = ${cfg.rootUrl}
27     [session]
28     COOKIE_NAME = session
29     COOKIE_SECURE = ${lib.boolToString cfg.cookieSecure}
31     [security]
32     SECRET_KEY = #secretkey#
33     INSTALL_LOCK = true
35     [log]
36     ROOT_PATH = ${cfg.stateDir}/log
38     ${cfg.extraConfig}
39   '';
43   options = {
44     services.gogs = {
45       enable = lib.mkOption {
46         default = false;
47         type = lib.types.bool;
48         description = "Enable Go Git Service.";
49       };
51       useWizard = lib.mkOption {
52         default = false;
53         type = lib.types.bool;
54         description = "Do not generate a configuration and use Gogs' installation wizard instead. The first registered user will be administrator.";
55       };
57       stateDir = lib.mkOption {
58         default = "/var/lib/gogs";
59         type = lib.types.str;
60         description = "Gogs data directory.";
61       };
63       user = lib.mkOption {
64         type = lib.types.str;
65         default = "gogs";
66         description = "User account under which Gogs runs.";
67       };
69       group = lib.mkOption {
70         type = lib.types.str;
71         default = "gogs";
72         description = "Group account under which Gogs runs.";
73       };
75       database = {
76         type = lib.mkOption {
77           type = lib.types.enum [ "sqlite3" "mysql" "postgres" ];
78           example = "mysql";
79           default = "sqlite3";
80           description = "Database engine to use.";
81         };
83         host = lib.mkOption {
84           type = lib.types.str;
85           default = "127.0.0.1";
86           description = "Database host address.";
87         };
89         port = lib.mkOption {
90           type = lib.types.port;
91           default = 3306;
92           description = "Database host port.";
93         };
95         name = lib.mkOption {
96           type = lib.types.str;
97           default = "gogs";
98           description = "Database name.";
99         };
101         user = lib.mkOption {
102           type = lib.types.str;
103           default = "gogs";
104           description = "Database user.";
105         };
107         password = lib.mkOption {
108           type = lib.types.str;
109           default = "";
110           description = ''
111             The password corresponding to {option}`database.user`.
112             Warning: this is stored in cleartext in the Nix store!
113             Use {option}`database.passwordFile` instead.
114           '';
115         };
117         passwordFile = lib.mkOption {
118           type = lib.types.nullOr lib.types.path;
119           default = null;
120           example = "/run/keys/gogs-dbpassword";
121           description = ''
122             A file containing the password corresponding to
123             {option}`database.user`.
124           '';
125         };
127         path = lib.mkOption {
128           type = lib.types.str;
129           default = "${cfg.stateDir}/data/gogs.db";
130           defaultText = lib.literalExpression ''"''${config.${opt.stateDir}}/data/gogs.db"'';
131           description = "Path to the sqlite3 database file.";
132         };
133       };
135       appName = lib.mkOption {
136         type = lib.types.str;
137         default = "Gogs: Go Git Service";
138         description = "Application name.";
139       };
141       repositoryRoot = lib.mkOption {
142         type = lib.types.str;
143         default = "${cfg.stateDir}/repositories";
144         defaultText = lib.literalExpression ''"''${config.${opt.stateDir}}/repositories"'';
145         description = "Path to the git repositories.";
146       };
148       domain = lib.mkOption {
149         type = lib.types.str;
150         default = "localhost";
151         description = "Domain name of your server.";
152       };
154       rootUrl = lib.mkOption {
155         type = lib.types.str;
156         default = "http://localhost:3000/";
157         description = "Full public URL of Gogs server.";
158       };
160       httpAddress = lib.mkOption {
161         type = lib.types.str;
162         default = "0.0.0.0";
163         description = "HTTP listen address.";
164       };
166       httpPort = lib.mkOption {
167         type = lib.types.port;
168         default = 3000;
169         description = "HTTP listen port.";
170       };
172       cookieSecure = lib.mkOption {
173         type = lib.types.bool;
174         default = false;
175         description = ''
176           Marks session cookies as "secure" as a hint for browsers to only send
177           them via HTTPS. This option is recommend, if Gogs is being served over HTTPS.
178         '';
179       };
181       extraConfig = lib.mkOption {
182         type = lib.types.str;
183         default = "";
184         description = "Configuration lines appended to the generated Gogs configuration file.";
185       };
186     };
187   };
189   config = lib.mkIf cfg.enable {
191     systemd.services.gogs = {
192       description = "Gogs (Go Git Service)";
193       after = [ "network.target" ];
194       wantedBy = [ "multi-user.target" ];
195       path = [ pkgs.gogs ];
197       preStart = let
198         runConfig = "${cfg.stateDir}/custom/conf/app.ini";
199         secretKey = "${cfg.stateDir}/custom/conf/secret_key";
200       in ''
201         mkdir -p ${cfg.stateDir}
203         # copy custom configuration and generate a random secret key if needed
204         ${lib.optionalString (cfg.useWizard == false) ''
205           mkdir -p ${cfg.stateDir}/custom/conf
206           cp -f ${configFile} ${runConfig}
208           if [ ! -e ${secretKey} ]; then
209               head -c 16 /dev/urandom | base64 > ${secretKey}
210           fi
212           KEY=$(head -n1 ${secretKey})
213           DBPASS=$(head -n1 ${cfg.database.passwordFile})
214           sed -e "s,#secretkey#,$KEY,g" \
215               -e "s,#dbpass#,$DBPASS,g" \
216               -i ${runConfig}
217         ''}
219         mkdir -p ${cfg.repositoryRoot}
220         # update all hooks' binary paths
221         HOOKS=$(find ${cfg.repositoryRoot} -mindepth 4 -maxdepth 4 -type f -wholename "*git/hooks/*")
222         if [ "$HOOKS" ]
223         then
224           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/gogs,${pkgs.gogs}/bin/gogs,g' $HOOKS
225           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/env,${pkgs.coreutils}/bin/env,g' $HOOKS
226           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/bash,${pkgs.bash}/bin/bash,g' $HOOKS
227           sed -ri 's,/nix/store/[a-z0-9.-]+/bin/perl,${pkgs.perl}/bin/perl,g' $HOOKS
228         fi
229       '';
231       serviceConfig = {
232         Type = "simple";
233         User = cfg.user;
234         Group = cfg.group;
235         WorkingDirectory = cfg.stateDir;
236         ExecStart = "${pkgs.gogs}/bin/gogs web";
237         Restart = "always";
238         UMask = "0027";
239       };
241       environment = {
242         USER = cfg.user;
243         HOME = cfg.stateDir;
244         GOGS_WORK_DIR = cfg.stateDir;
245       };
246     };
248     users = lib.mkIf (cfg.user == "gogs") {
249       users.gogs = {
250         description = "Go Git Service";
251         uid = config.ids.uids.gogs;
252         group = "gogs";
253         home = cfg.stateDir;
254         createHome = true;
255         shell = pkgs.bash;
256       };
257       groups.gogs.gid = config.ids.gids.gogs;
258     };
260     warnings = lib.optional (cfg.database.password != "")
261       ''config.services.gogs.database.password will be stored as plaintext
262         in the Nix store. Use database.passwordFile instead.'';
264     # Create database passwordFile default when password is configured.
265     services.gogs.database.passwordFile =
266       (lib.mkDefault (toString (pkgs.writeTextFile {
267         name = "gogs-database-password";
268         text = cfg.database.password;
269       })));
270   };