diff --git a/services/default.nix b/services/default.nix index cd25088..0599eb5 100644 --- a/services/default.nix +++ b/services/default.nix @@ -6,6 +6,7 @@ ./netbox ./ofborg ./postgres + ./forgejo ./baremetal-builder ]; } diff --git a/services/forgejo/default.nix b/services/forgejo/default.nix new file mode 100644 index 0000000..8df6de6 --- /dev/null +++ b/services/forgejo/default.nix @@ -0,0 +1,119 @@ +{ pkgs, lib, config, ... }: + + +let + cfg = config.bagel.services.forgejo; + inherit (lib) mkIf mkEnableOption mkOption types; + + domain = "git.forkos.org"; +in +{ + options.bagel.services.forgejo = { + enable = mkEnableOption "Forgejo"; + sshBindAddr = mkOption { + type = types.str; + }; + }; + + config = mkIf cfg.enable { + services.forgejo = { + enable = true; + + package = pkgs.callPackage ../../pkgs/forgejo { }; + + database = { + type = "postgres"; + createDatabase = true; + }; + + lfs.enable = true; + + settings = { + DEFAULT = { + APP_NAME = "ForkOS"; + }; + + server = { + PROTOCOL = "http+unix"; + ROOT_URL = "https://${domain}/"; + DOMAIN = "${domain}"; + + BUILTIN_SSH_SERVER_USER = "git"; + SSH_PORT = 22; + SSH_LISTEN_HOST = cfg.sshBindAddr; + START_SSH_SERVER = true; + }; + + session = { + PROVIDER = "db"; + COOKIE_NAME = "session"; + }; + + # TODO: SSO, disable registrations + # TODO: transactional mails + # TODO: redis cache instead of default in-memory + + ui = { + SHOW_USER_EMAIL = false; + }; + + repository = { + # Forks in forgejo are suprisingly expensive because they are full git clones. + # If we do want to enable forks, we can write a small patch that disables + # only for repositories that are as large as nixpkgs. + DISABLE_FORKS = true; + }; + + packages = { + # Forgejo's various package registries can easily take up a lot of space. + # We could either store the blobs on some slower disks but larger, or even + # better, use an s3 bucket for it. But until we actually have a use-case for + # this feature, we will simply keep it disabled for now. + ENABLED = false; + }; + + indexer = { + REPO_INDEXER_REPO_TYPES = "sources,mirrors,templates"; # skip forks + REPO_INDEXER_ENABLED = true; + ISSUE_INDEXER_TYPE = "bleve"; + }; + + "git.timeout" = { + MIGRATE = 3600; # increase from default 600 (seconds) for something as large as nixpkgs on a slow uplink + }; + + log = { + LEVEL = "Warn"; + }; + }; + }; + + systemd.services.forgejo = { + serviceConfig = lib.optionalAttrs (config.services.forgejo.settings.server.SSH_PORT < 1024) { + AmbientCapabilities = lib.mkForce "CAP_NET_BIND_SERVICE"; + CapabilityBoundingSet = lib.mkForce "CAP_NET_BIND_SERVICE"; + PrivateUsers = lib.mkForce false; + }; + + # start Forgejo *after* sshd.service, so in case Forgejo tries to wildcard bind :22 due to + # a bug or whatever, we don't lose OpenSSH in a race. + wants = [ "sshd.service" ]; + requires = [ "sshd.service" ]; + }; + + services.nginx = { + enable = true; + virtualHosts.${domain} = { + enableACME = true; + forceSSL = true; + locations."/".proxyPass = "http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}"; + }; + }; + + networking.firewall.allowedTCPPorts = [ + 80 + 443 + config.services.forgejo.settings.server.SSH_PORT + ]; + }; +}