{ config, lib, pkgs, ... }: let inherit (lib) mkEnableOption mkIf mkOption ; cfg = config.my.services.gitea; my = config.my; domain = config.networking.domain; hostname = config.networking.hostName; fqdn = "${hostname}.${domain}"; giteaUser = "git"; in { options.my.services.gitea = let inherit (lib) types; in { enable = mkEnableOption "Personal Git hosting with Gitea"; privatePort = mkOption { type = types.port; default = 8082; example = 8082; description = "Port to serve the app"; }; }; config = mkIf cfg.enable { # use git as user to have `git clone git@git.domain` users.users.${giteaUser} = { description = "Gitea Service"; home = config.services.gitea.stateDir; useDefaultShell = true; group = giteaUser; # the systemd service for the gitea module seems to hardcode the group as # gitea, so, uh, just in case? extraGroups = ["gitea"]; isSystemUser = true; }; users.groups.${giteaUser} = {}; services.gitea = { enable = true; user = giteaUser; appName = "Personal Forge"; lfs.enable = true; settings = { server = { ROOT_URL = "https://git.${domain}/"; DOMAIN = "git.${domain}"; HTTP_ADDR = "127.0.0.1"; HTTP_PORT = cfg.privatePort; }; log.LEVEL = "Warn"; # [ "Trace" "Debug" "Info" "Warn" "Error" "Critical" ] other.SHOW_FOOTER_VERSION = false; repository = { ENABLE_PUSH_CREATE_USER = true; DEFAULT_BRANCH = "main"; }; # NOTE: temporarily remove this for initial setup service.DISABLE_REGISTRATION = true; # only send cookies via HTTPS session.COOKIE_SECURE = true; }; # NixOS module uses `gitea dump` to backup repositories and the database, # but it produces a single .zip file that's not very restic friendly. # I configure my backup system manually below. dump.enable = false; database = { type = "postgres"; # user needs to be the same as gitea user user = giteaUser; # FIXME: change database name to match 23.11 postgres changes around ensureDatabase createDatabase = false; }; }; # FIXME: Borg *could* be backing up files while they're being edited by # gitea, so it may produce corrupt files in the snapshot if I push stuff # around midnight. I'm not sure how `gitea dump` handles this either, # though. my.services.restic-backup = { paths = [ config.services.gitea.lfs.contentDir config.services.gitea.repositoryRoot ]; }; # NOTE: no need to use postgresql.ensureDatabases because the gitea module # takes care of this automatically services.postgresqlBackup = { databases = [config.services.gitea.database.name]; }; services.nginx = { virtualHosts = { "git.${domain}" = { forceSSL = true; useACMEHost = fqdn; locations."/" = { proxyPass = "http://127.0.0.1:${toString cfg.privatePort}"; }; }; }; }; security.acme.certs.${fqdn}.extraDomainNames = ["git.${domain}"]; systemd.services.gitea.preStart = "${pkgs.coreutils}/bin/ln -sfT ${./templates} ${config.services.gitea.stateDir}/custom/templates"; }; }