{config, ...}: let
  domain = "gitea.${config.services.nginx.domain}";
in {
  services.gitea = {
    inherit domain;
    enable = true;

    httpAddress = "127.0.0.1";
    database.type = "postgres";

    rootUrl = "https://${domain}/";

    appName = "Gitea: Git with a cup of tea";

    settings = {
      server.SSH_PORT = 2222;
      service.DISABLE_REGISTRATION = true;
      session.COOKIE_SECURE = true;
    };
  };

  # Set up SSL
  services.nginx.virtualHosts."${domain}" = let
    inherit (config.services.gitea) httpAddress httpPort;
  in {
    forceSSL = true;
    enableACME = true;
    extraConfig = ''
      add_header Strict-Transport-Security "max-age=15552000; includeSubDomains" always;
    '';

    locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
  };

  # Block repeated failed login attempts
  #
  # TODO(tlater): Update to the new regex, since apparently this one
  # is deprecated (but the new one doesn't work on the current version
  # of gitea yet): https://docs.gitea.io/en-us/fail2ban-setup/
  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=gitea.service + _COMM=gitea + SYSLOG_IDENTIFIER=gitea
    '';
  };

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