Commit 119b7dc
Changed files (2)
modules
services
forgejo
modules/services/forgejo/runner.nix
@@ -0,0 +1,124 @@
+{
+ den,
+ lib,
+ inputs,
+ ...
+}: {
+ den.aspects.services.forgejo.runner = {
+ includes = [den.aspects.services.podman];
+ settings = {
+ instances = lib.mkOption {
+ type = lib.types.attrsOf (lib.types.submodule ({name, ...}: {
+ options = {
+ name = lib.mkoption {
+ type = lib.types.str;
+ default = name;
+ };
+ servers = lib.mkOption {
+ type = lib.attrsOf (lib.types.submodule {
+ options = {
+ url = lib.mkOption {
+ type = lib.types.str;
+ };
+ uuid = lib.mkOption {
+ type = lib.types.str;
+ };
+ tokenFileAged = lib.mkOption {
+ type = lib.types.path;
+ };
+ labels = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ description = "Extra labels used for this server.";
+ default = [];
+ };
+ };
+ });
+ default = {};
+ };
+ labels = lib.mkOption {
+ type = lib.types.listOf lib.types.str;
+ default = [];
+ };
+ extraEnvironments = lib.mkOption {
+ type = lib.types.attrsOf lib.types.str;
+ default = {};
+ };
+ extraSettings = lib.mkOption {
+ type = lib.types.attrsOf lib.types.anything;
+ default = {};
+ };
+ };
+ }));
+ default = {};
+ };
+ };
+
+ nixos = {
+ host,
+ config,
+ ...
+ }: let
+ cfg = host.settings.services.forgejo.runner;
+ mkServerTokenSecretName = instance: server: "forgejo-runner-${instance}-${server}-token";
+ in {
+ imports = [inputs.nur-hpcesia.nixosModules.forgejo-runner];
+
+ # If you would like to use docker runners in combination with cache actions,
+ # be sure to add docker bridge interfaces “br-*” to the firewalls’ trusted interfaces.
+ # See https://forgejo.org/docs/next/admin/actions/runner-installation/#nixos
+ networking.firewall.trustedInterfaces =
+ if (config.networking.nftables.enable)
+ then ["br-*"]
+ else ["br-+"];
+
+ services.forgejo-runner.instances =
+ lib.mapAttrs (instance: instanceCfg: {
+ enable = true;
+ inherit (instanceCfg) name labels;
+
+ servers =
+ lib.mapAttrs (server: serverCfg: {
+ inherit (serverCfg) url uuid;
+ tokenFile = "$CREDENTIALS_DIRECTORY/${server}-token";
+ labels = lib.unique (instanceCfg.labels ++ (serverCfg.labels));
+ })
+ instanceCfg.servers;
+
+ settings = lib.mkMerge [
+ {
+ cache = {
+ enabled = true;
+ host = "172.17.0.1";
+ };
+ container = {
+ enable_ipv6 = true;
+ options = "--cap-add sys_admin --cap-add mknod --device /dev/fuse";
+ };
+ }
+ instanceCfg.extraSettings
+ ];
+ })
+ cfg.instances;
+
+ systemd.services = lib.mapAttrs' (instance: instanceCfg:
+ lib.nameValuePair "forgejo-runner-${instance}" {
+ serviceConfig.LoadCredential =
+ lib.map
+ (server: "${server}-token:${config.vaultix.secrets.${mkServerTokenSecretName instance server}.path}")
+ (lib.attrNames instanceCfg.servers);
+ })
+ cfg.instances;
+
+ vaultix.secrets = lib.mergeAttrsList (
+ lib.mapAttrsToList (instance: instanceCfg:
+ lib.mapAttrs' (
+ server: serverCfg:
+ lib.nameValuePair (mkServerTokenSecretName instance server) {
+ file = serverCfg.tokenFileAged;
+ }
+ ))
+ cfg.instances
+ );
+ };
+ };
+}
modules/services/forgejo.nix
@@ -0,0 +1,126 @@
+{lib, ...}: {
+ den.aspects.services.forgejo = {
+ settings = {
+ external = lib.mkEnableOption "Whether to expose Forgejo service to public internet";
+ domain = lib.mkOption {
+ type = lib.types.str;
+ };
+ address = lib.mkOption {
+ type = lib.types.str;
+ default = "127.0.0.1";
+ };
+ port = lib.mkOption {
+ type = lib.types.port;
+ default = 3155;
+ };
+ };
+
+ reverseProxy = {host, ...}: let
+ cfg = host.settings.services.forgejo;
+ in
+ lib.optionalAttrs (cfg.external) {
+ ${cfg.domain} = {
+ port = cfg.port;
+ };
+ };
+
+ reverseProxyTailscale = {host, ...}: let
+ cfg = host.settings.services.forgejo;
+ in
+ lib.optionalAttrs (!cfg.external) {
+ ${cfg.domain} = {
+ port = cfg.port;
+ };
+ };
+
+ persist = {config, ...}: {
+ directories = [
+ {
+ directory = config.services.forgejo.stateDir;
+ inherit (config.services.forgejo) user group;
+ mode = "0700";
+ }
+ ];
+ };
+
+ nixos = {
+ host,
+ config,
+ ...
+ }: let
+ hostCfg = host.settings.services.forgejo;
+ in {
+ services.forgejo = {
+ enable = true;
+ user = "git";
+ group = "forgejo";
+ database = {
+ type = "sqlite3";
+ };
+ lfs.enable = true;
+ settings = {
+ DEFAULT = {
+ APP_NAME = "Gate Of Infinity";
+ APP_SLOGAN = "Walk toward the tomorrow where the stars gleam.";
+ APP_DISPLAY_NAME_FORMAT = "{APP_NAME}";
+ };
+ server = {
+ DOMAIN = hostCfg.domain;
+ HTTP_ADDR = hostCfg.address;
+ HTTP_PORT = hostCfg.port;
+ SSH_PORT =
+ if hostCfg.external
+ then host.settings.core.openssh.access.port
+ else 22;
+ PROTOCOL = "http";
+ ROOT_URL = "http${lib.optionalString hostCfg.external "s"}://${hostCfg.domain}/";
+ };
+ service = {
+ DISABLE_REGISTRATION = true;
+ ENABLE_BASIC_AUTHENTICATION = false;
+ };
+ repository = {
+ DEFAULT_REPO_UNITS = "repo.code,repo.releases,repo.issues,repo.pulls";
+ DEFAULT_FORK_REPO_UNITS = "repo.code,repo.pulls";
+ DEFAULT_MIRROR_REPO_UNITS = "repo.code";
+ };
+ actions = {
+ ENABLED = true;
+ DEFAULT_ACTIONS_URL = "http${lib.optionalString hostCfg.external "s"}://${hostCfg.domain}";
+ };
+ webhook = {
+ ALLOWED_HOST_LIST = "external,loopback";
+ };
+ log = {
+ LEVEL = "Info";
+ LOGGER_ROUTER_MODE = "Error";
+ };
+ ui = {
+ THEMES = lib.concatStringsSep "," [
+ "forgejo-auto"
+ "forgejo-light"
+ "forgejo-dark"
+ "gitea-auto"
+ "gitea-light"
+ "gitea-dark"
+ ];
+ };
+ };
+ };
+
+ users.users."git" = {
+ isSystemUser = true;
+ useDefaultShell = true;
+ group = config.services.forgejo.group;
+ home = config.services.forgejo.stateDir;
+ };
+
+ services.openssh = {
+ extraConfig = ''
+ Match User git
+ AcceptEnv GIT_PROTOCOL
+ '';
+ };
+ };
+ };
+}