1 { config, lib, options, pkgs, ... }:
3 cfg = config.services.gogs;
4 opt = options.services.gogs;
5 configFile = pkgs.writeText "app.ini" ''
6 BRAND_NAME = ${cfg.appName}
11 TYPE = ${cfg.database.type}
12 HOST = ${cfg.database.host}:${toString cfg.database.port}
13 NAME = ${cfg.database.name}
14 USER = ${cfg.database.user}
16 PATH = ${cfg.database.path}
19 ROOT = ${cfg.repositoryRoot}
22 DOMAIN = ${cfg.domain}
23 HTTP_ADDR = ${cfg.httpAddress}
24 HTTP_PORT = ${toString cfg.httpPort}
25 EXTERNAL_URL = ${cfg.rootUrl}
29 COOKIE_SECURE = ${lib.boolToString cfg.cookieSecure}
32 SECRET_KEY = #secretkey#
36 ROOT_PATH = ${cfg.stateDir}/log
45 enable = lib.mkOption {
47 type = lib.types.bool;
48 description = "Enable Go Git Service.";
51 useWizard = lib.mkOption {
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.";
57 stateDir = lib.mkOption {
58 default = "/var/lib/gogs";
60 description = "Gogs data directory.";
66 description = "User account under which Gogs runs.";
69 group = lib.mkOption {
72 description = "Group account under which Gogs runs.";
77 type = lib.types.enum [ "sqlite3" "mysql" "postgres" ];
80 description = "Database engine to use.";
85 default = "127.0.0.1";
86 description = "Database host address.";
90 type = lib.types.port;
92 description = "Database host port.";
98 description = "Database name.";
101 user = lib.mkOption {
102 type = lib.types.str;
104 description = "Database user.";
107 password = lib.mkOption {
108 type = lib.types.str;
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.
117 passwordFile = lib.mkOption {
118 type = lib.types.nullOr lib.types.path;
120 example = "/run/keys/gogs-dbpassword";
122 A file containing the password corresponding to
123 {option}`database.user`.
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.";
135 appName = lib.mkOption {
136 type = lib.types.str;
137 default = "Gogs: Go Git Service";
138 description = "Application name.";
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.";
148 domain = lib.mkOption {
149 type = lib.types.str;
150 default = "localhost";
151 description = "Domain name of your server.";
154 rootUrl = lib.mkOption {
155 type = lib.types.str;
156 default = "http://localhost:3000/";
157 description = "Full public URL of Gogs server.";
160 httpAddress = lib.mkOption {
161 type = lib.types.str;
163 description = "HTTP listen address.";
166 httpPort = lib.mkOption {
167 type = lib.types.port;
169 description = "HTTP listen port.";
172 cookieSecure = lib.mkOption {
173 type = lib.types.bool;
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.
181 extraConfig = lib.mkOption {
182 type = lib.types.str;
184 description = "Configuration lines appended to the generated Gogs configuration file.";
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 ];
198 runConfig = "${cfg.stateDir}/custom/conf/app.ini";
199 secretKey = "${cfg.stateDir}/custom/conf/secret_key";
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}
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" \
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/*")
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
235 WorkingDirectory = cfg.stateDir;
236 ExecStart = "${pkgs.gogs}/bin/gogs web";
244 GOGS_WORK_DIR = cfg.stateDir;
248 users = lib.mkIf (cfg.user == "gogs") {
250 description = "Go Git Service";
251 uid = config.ids.uids.gogs;
257 groups.gogs.gid = config.ids.gids.gogs;
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;