{
  config,
  pkgs,
  lib,
  systemConfig,
  common,
  ...
}:
let
  cfg = config.services.forgejo;
  srv = cfg.settings.server;
  domain = "beta.code.${common.domain}";
  passwordKey = "forgejo/admin-pass";
  runnerTokenKey = "forgejo/runner-token";
in
{
  services = {
    nginx.virtualHosts.${domain} = {
      enableACME = true;
      forceSSL = true;
      locations."/".proxyPass = "http://127.0.0.1:${builtins.toString srv.HTTP_PORT}";
      serverAliases = [ "beta.git.${common.domain}" ];
    };

    forgejo = {
      enable = true;
      database.type = "postgres";
      # Enable support for Git Large File Storage
      lfs.enable = true;

      secrets.mailer.PASSWD = config.sops.secrets."mailserver/password-hash".path;

      settings = {
        server = {
          DOMAIN = domain;
          # You need to specify this to remove the port from URLs in the web UI.
          ROOT_URL = "https://${domain}/";
          HTTP_PORT = 8002;
        };
        # You can temporarily allow registration to create an admin user.
        service.DISABLE_REGISTRATION = true;
        # Add support for actions, based on act: https://github.com/nektos/act
        actions = {
          ENABLED = true;
          DEFAULT_ACTIONS_URL = "github";
        };
        # Sending emails is completely optional
        # You can send a test email from the web UI at:
        # Profile Picture > Site Administration > Configuration >  Mailer Configuration
        mailer = lib.mkIf config.mailserver.enable {
          ENABLED = true;
          PROTOCOL = "smtps";
          SMTP_ADDR = config.mailserver.fqdn;
          FROM = "noreply-forgejo@${common.domain}";
          USER = "${systemConfig.username}@${common.domain}";
        };
      };
    };
    gitea-actions-runner = {
      package = pkgs.forgejo-actions-runner;
      instances.default = {
        enable = true;
        name = "monolith";
        url = "https://${domain}";
        # Obtaining the path to the runner token file may differ
        # tokenFile should be in format TOKEN=<secret>, since it's EnvironmentFile for systemd
        tokenFile = config.sops.secrets.${runnerTokenKey}.path;
        labels = [
          "docker:docker://node:20-bullseye"
          "native:host"
        ];
      };
    };
  };

  sops.secrets = {
    ${passwordKey}.owner = "forgejo";
    ${runnerTokenKey}.owner = "forgejo";
  };

  # Create a single admin user / update password if exists
  systemd.services.forgejo.preStart =
    let
      adminCmd = "${lib.getExe config.services.forgejo.package} admin user";
      pwd = config.sops.secrets.${passwordKey};
      user = "martin"; # Note, Forgejo doesn't allow creation of an account named "admin"
      email = "git@${common.domain}";
    in
    ''
      ${adminCmd} create --admin --email "${email}" --username ${user} --password "$(tr -d '\n' < ${pwd.path})" || true
      ## Alter an existing user. Will prompt new password on login
      # ${adminCmd} change-password --username ${user} --password "$(tr -d '\n' < ${pwd.path})" || true
    '';
}
