{ config, lib, pkgs, ... }: let cfg = config.services.forgejo; secrets = config.age.secrets; domain = "federez.net"; fqdn = "git.${domain}"; sys-ip = "193.54.193.164"; git-ip = "193.54.193.165"; in { age.secrets = lib.mapAttrs (_: f: { file = f; owner = cfg.user; group = cfg.group; }) { forgejo-db-pass = ../secrets/forgejo-db-pass.age; forgejo-wizard-user-pass = ../secrets/forgejo-wizard-user-pass.age; forgejo-mailbox-pass = ../secrets/forgejo-mailbox-pass.age; }; backups = { directories = [ cfg.stateDir ]; postgresqlDatabases = [ cfg.database.name ]; }; services.openssh = { listenAddresses = [{ addr = "${sys-ip}"; port = 22; }]; startWhenNeeded = false; }; services.forgejo = { enable = true; user = "forgejo"; package = pkgs.forgejo; stateDir = "/var/lib/forgejo"; database = { name = "forgejo"; type = "postgres"; socket = "/var/run/postgresql"; passwordFile = secrets.forgejo-db-pass.path; }; # Enable support for Git Large File Storage lfs.enable = true; settings = { server = { DOMAIN = "${fqdn}"; ROOT_URL = "https://${fqdn}/"; HTTP_PORT = 3000; SSH_LISTEN_HOST = "${git-ip}"; SSH_PORT = 22; SSH_LISTEN_PORT = 22; START_SSH_SERVER = true; # Forgejo is installed under the forgejo user # The builtin ssh server user must match this BUILTIN_SSH_SERVER_USER = "${cfg.user}"; }; service = { # Disable internal registration only DISABLE_REGISTRATION = true; ALLOW_ONLY_EXTERNAL_REGISTRATION = false; ENABLE_INTERNAL_SIGNIN = true; ENABLE_BASIC_AUTHENTICATION = true; ENABLE_NOTIFY_MAIL = true; # Privacy DEFAULT_KEEP_EMAIL_PRIVATE = true; DEFAULT_USER_VISIBILITY = "private"; }; repository = { # Enable git clone over HTTP DISABLE_HTTP_GIT = false; }; mailer = { ENABLED = true; SMTP_ADDR = "${domain}"; SMTP_PORT = 465; FROM = "forge@${domain}"; USER = "forge@${domain}"; }; }; secrets = { mailer = { PASSWD = secrets.forgejo-mailbox-pass.path; }; }; }; systemd.services.forgejo.preStart = let adminCmd = "${lib.getExe cfg.package} admin user"; pwd = secrets.forgejo-wizard-user-pass.path; # Note, Forgejo doesn't allow creation of an account named "admin" # Note: that username MUST be unpickable by a user signin-up to re2o endpoint # WARN: Never change the username without deleting manually the account (it will otherwise continue to exists) user = "wizard"; in '' # || true -> avoid systemd to crash on that command if user already exist by forcing a 0 return value ${adminCmd} create --admin --email "root@localhost" --username ${user} --password "$(tr -d '\n' < ${pwd})" || true ${adminCmd} change-password --username ${user} --password "$(tr -d '\n' < ${pwd})" || true ''; systemd.services.forgejo.serviceConfig = { AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; PrivateUsers = lib.mkForce false; }; services.nginx = { enable = true; recommendedProxySettings = true; virtualHosts = { "git.federez.net" = { enableACME = true; forceSSL = true; locations."/".proxyPass = "http://localhost:3000"; }; }; }; networking.firewall.allowedTCPPorts = [ 80 443 ]; }