{
  pkgs,
  config,
  lib,
  ...
}:
let
  nextcloud = pkgs.nextcloud31;
  hostName = "nextcloud.${config.services.nginx.domain}";
in
{
  networking.firewall.allowedTCPPorts = [
    80
    443
  ];

  services = {
    nextcloud = {
      inherit hostName;

      package = nextcloud;
      phpPackage = lib.mkForce (
        pkgs.php.override {
          packageOverrides = _: prev: {
            extensions = prev.extensions // {
              pgsql = prev.extensions.pgsql.overrideAttrs (_: {
                configureFlags = [ "--with-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ];
              });
              pdo_pgsql = prev.extensions.pdo_pgsql.overrideAttrs (_: {
                configureFlags = [ "--with-pdo-pgsql=${lib.getDev config.services.postgresql.package.pg_config}" ];
              });
            };
          };
        }
      );
      enable = true;
      maxUploadSize = "2G";
      https = true;

      configureRedis = true;

      config = {
        dbtype = "pgsql";
        dbhost = "/run/postgresql";

        adminuser = "tlater";
        adminpassFile = config.sops.secrets."nextcloud/tlater".path;
      };

      settings = {
        default_phone_region = "AT";
        overwriteprotocol = "https";
      };

      phpOptions = {
        "opcache.interned_strings_buffer" = "16";
      };

      extraApps = {
        inherit (config.services.nextcloud.package.packages.apps)
          calendar
          contacts
          cookbook
          news
          ;
      };
    };

    # Set up SSL
    nginx.virtualHosts."${hostName}" = {
      forceSSL = true;
      useACMEHost = "tlater.net";
      # The upstream module already adds HSTS
    };

    backups.nextcloud = {
      user = "nextcloud";
      paths = [
        "/var/lib/nextcloud/nextcloud-db.sql"
        "/var/lib/nextcloud/data/"
        "/var/lib/nextcloud/config/config.php"
      ];
      preparation = {
        packages = [
          config.services.postgresql.package
          config.services.nextcloud.occ
        ];
        text = ''
          nextcloud-occ maintenance:mode --on
          pg_dump ${config.services.nextcloud.config.dbname} --file=/var/lib/nextcloud/nextcloud-db.sql
        '';
      };
      cleanup = {
        packages = [
          pkgs.coreutils
          config.services.nextcloud.occ
        ];
        text = ''
          rm /var/lib/nextcloud/nextcloud-db.sql
          nextcloud-occ maintenance:mode --off
        '';
      };
    };
  };

  # Ensure that this service doesn't start before postgres is ready
  systemd.services.nextcloud-setup.after = [ "postgresql.service" ];

  sops.secrets."nextcloud/tlater" = {
    owner = "nextcloud";
    group = "nextcloud";
  };
}
