{
  pkgs,
  config,
  lib,
  ...
}: let
  domain = "gitea.${config.services.nginx.domain}";
in {
  services.forgejo = {
    enable = true;
    database.type = "postgres";

    settings = {
      server = {
        DOMAIN = domain;
        HTTP_ADDR = "127.0.0.1";
        ROOT_URL = "https://${domain}/";
        SSH_PORT = 2222;
      };

      metrics = {
        ENABLED = true;
        TOKEN = "#metricstoken#";
      };
      service.DISABLE_REGISTRATION = true;
      session.COOKIE_SECURE = true;
    };
  };

  systemd.services.forgejo.serviceConfig.ExecStartPre = let
    replaceSecretBin = "${pkgs.replace-secret}/bin/replace-secret";
    secretPath = config.sops.secrets."forgejo/metrics-token".path;
    runConfig = "${config.services.forgejo.customDir}/conf/app.ini";
  in [
    "+${replaceSecretBin} '#metricstoken#' '${secretPath}' '${runConfig}'"
  ];

  # Set up SSL
  services.nginx.virtualHosts."${domain}" = let
    httpAddress = config.services.forgejo.settings.server.HTTP_ADDR;
    httpPort = config.services.forgejo.settings.server.HTTP_PORT;
  in {
    forceSSL = true;
    enableACME = true;
    extraConfig = ''
      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
      access_log /var/log/nginx/${domain}/access.log upstream_time;
    '';

    locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
    locations."/metrics" = {
      extraConfig = ''
        access_log off;
        allow 127.0.0.1;
        ${lib.optionalString config.networking.enableIPv6 "allow ::1;"}
        deny all;
      '';
    };
  };

  # Block repeated failed login attempts
  #
  # TODO(tlater): Update this - we switched to forgejo, who knows what
  # the new matches are.
  # environment.etc = {
  #   "fail2ban/filter.d/gitea.conf".text = ''
  #     [Definition]
  #     failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
  #     journalmatch = _SYSTEMD_UNIT=forgejo.service + _COMM=forgejo + SYSLOG_IDENTIFIER=forgejo
  #   '';
  # };

  # services.fail2ban.jails = {
  #   gitea = ''
  #     enabled = true
  #   '';
  # };

  # services.backups.forgejo = {
  #   user = "forgejo";
  #   paths = [
  #     "/var/lib/forgejo/forgejo-db.sql"
  #     "/var/lib/forgejo/repositories/"
  #     "/var/lib/forgejo/data/"
  #     "/var/lib/forgejo/custom/"
  #     # Conf is backed up via nix
  #   ];
  #   preparation = {
  #     packages = [config.services.postgresql.package];
  #     text = "pg_dump ${config.services.forgejo.database.name} --file=/var/lib/forgejo/forgejo-db.sql";
  #   };
  #   cleanup = {
  #     packages = [pkgs.coreutils];
  #     text = "rm /var/lib/forgejo/forgejo-db.sql";
  #   };
  #   pauseServices = ["forgejo.service"];
  # };
}