{
  name = "Forgejo";
  description = ''
    Forgejo git server
  '';

  traefikRoutes =
    {
      host,
      ...
    }:
    let
      hostname = host.hostname;
      config = host.config.forgejo;
    in
    [
      {
        name = "${hostname}-forgejo";
        rule = "Host(`${config.domain}`)";
        target = "http://${host.ip}:3000";
      }
    ];

  nixosModule =
    {
      pkgs,
      lib,
      config,
      ...
    }:
    {
      options.forgejo = {
        domain = lib.mkOption {
          type = lib.types.str;
        };
      };

      config =
        let
          cfg = config.forgejo;
          secrets = config.sops.secrets;
        in
        {
          networking.firewall.allowedTCPPorts = [
            3000 # Forgejo
            2222 # Forgejo built-in ssh server
          ];

          # Create the database
          postgres.databases = [ "forgejo" ];

          sops.secrets = {
            "forgejo/db_pass" = {
              owner = "forgejo";
            };
            "forgejo/email_host" = {
              owner = "forgejo";
            };
            "forgejo/email_port" = {
              owner = "forgejo";
            };
            "forgejo/email_from" = {
              owner = "forgejo";
            };
            "forgejo/email_username" = {
              owner = "forgejo";
            };
            "forgejo/email_password" = {
              owner = "forgejo";
            };
          };

          environment.systemPackages =
            let
              forgejo-cli = pkgs.writeShellScriptBin "forgejo-cli" ''
                if [ $# -eq 0 ]; then
                    echo "No arguments supplied"
                    exit 1
                fi
                sudo -u forgejo -- ${lib.getExe pkgs.forgejo} --config /cephfs/appdata/forgejo/custom/conf/app.ini $@
              '';
            in
            [
              forgejo-cli
            ];

          services.forgejo = {
            enable = true;
            package = pkgs.forgejo;
            stateDir = "/cephfs/appdata/forgejo";
            lfs.enable = true;

            database = {
              type = "postgres";
              passwordFile = secrets."forgejo/db_pass".path;
            };

            settings = {
              repository = {
                ENABLE_PUSH_CREATE_USER = true;
                ENABLE_PUSH_CREATE_ORG = true;
              };

              server = {
                DOMAIN = cfg.domain;
                # You need to specify this to remove the port from URLs in the web UI.
                ROOT_URL = "https://${cfg.domain}/";
                HTTP_PORT = 3000;

                START_SSH_SERVER = true;
                SSH_PORT = 2222;
                SSH_LISTEN_PORT = 2222;
                BUILTIN_SSH_SERVER_USER = "git";
              };

              service = {
                REGISTER_EMAIL_CONFIRM = true;
                DISABLE_REGISTRATION = true;
                ENABLE_NOTIFY_MAIL = true;
              };

              admin.DISABLE_REGULAR_ORG_CREATION = true;

              actions = {
                ENABLED = true;
                DEFAULT_ACTIONS_URL = "github";
              };

              mailer = {
                ENABLED = true;
              };

              picture = {
                DISABLE_GRAVATAR = false;
                ENABLE_FEDERATED_AVATAR = true;
              };
            };

            secrets = {
              mailer = {
                SMTP_ADDR = secrets."forgejo/email_host".path;
                SMTP_PORT = secrets."forgejo/email_port".path;
                FROM = secrets."forgejo/email_from".path;
                USER = secrets."forgejo/email_username".path;
                PASSWD = secrets."forgejo/email_password".path;
              };
            };
          };
        };
    };
}