mirror of
				https://github.com/nmasur/dotfiles
				synced 2025-11-04 11:43:16 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			237 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			237 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{
 | 
						|
  config,
 | 
						|
  pkgs,
 | 
						|
  lib,
 | 
						|
  ...
 | 
						|
}:
 | 
						|
 | 
						|
let
 | 
						|
  inherit (config.nmasur.settings) hostnames username;
 | 
						|
  cfg = config.nmasur.presets.services.nextcloud;
 | 
						|
in
 | 
						|
{
 | 
						|
 | 
						|
  options.nmasur.presets.services.nextcloud.enable = lib.mkEnableOption "Nextcloud private data hub";
 | 
						|
 | 
						|
  config = lib.mkIf cfg.enable {
 | 
						|
 | 
						|
    services.nextcloud = {
 | 
						|
      enable = true;
 | 
						|
      package = pkgs.nextcloud32; # Required to specify
 | 
						|
      configureRedis = true;
 | 
						|
      datadir = "/data/nextcloud";
 | 
						|
      database.createLocally = true;
 | 
						|
      https = true;
 | 
						|
      hostName = "localhost";
 | 
						|
      maxUploadSize = "50G";
 | 
						|
      config = {
 | 
						|
        adminpassFile = config.secrets.nextcloud.dest;
 | 
						|
        dbtype = "pgsql"; # Enables postgresql
 | 
						|
      };
 | 
						|
      settings = {
 | 
						|
        default_phone_region = "US";
 | 
						|
        # Allow access when hitting either of these hosts or IPs
 | 
						|
        trusted_domains = [ hostnames.content ];
 | 
						|
        trusted_proxies = [ "127.0.0.1" ];
 | 
						|
        maintenance_window_start = 4; # Run jobs at 4am UTC
 | 
						|
        log_type = "file";
 | 
						|
        loglevel = 1; # Include all actions in the log
 | 
						|
      };
 | 
						|
      extraAppsEnable = true;
 | 
						|
      extraApps = {
 | 
						|
        calendar = config.services.nextcloud.package.packages.apps.calendar;
 | 
						|
        contacts = config.services.nextcloud.package.packages.apps.contacts;
 | 
						|
        # These apps are defined and pinned by overlay in flake.
 | 
						|
        # news = pkgs.nextcloudApps.news;
 | 
						|
        # external = pkgs.nextcloudApps.external;
 | 
						|
        # cookbook = pkgs.nextcloudApps.cookbook;
 | 
						|
        # snappymail = pkgs.nextcloudApps.snappymail;
 | 
						|
      };
 | 
						|
      phpOptions = {
 | 
						|
        "opcache.interned_strings_buffer" = "16";
 | 
						|
        "output_buffering" = "0";
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    # Don't let Nginx use main ports (using Caddy instead)
 | 
						|
    services.nginx.enable = false;
 | 
						|
 | 
						|
    services.phpfpm.pools.nextcloud.settings = {
 | 
						|
      "listen.owner" = config.services.caddy.user;
 | 
						|
      "listen.group" = config.services.caddy.group;
 | 
						|
    };
 | 
						|
    users.users.caddy.extraGroups = [ "nextcloud" ];
 | 
						|
 | 
						|
    # Point Caddy to Nginx
 | 
						|
    nmasur.presets.services.caddy.routes = [
 | 
						|
      {
 | 
						|
        match = [ { host = [ hostnames.content ]; } ];
 | 
						|
        handle = [
 | 
						|
          {
 | 
						|
            handler = "subroute";
 | 
						|
            routes = [
 | 
						|
              # Sets variables and headers
 | 
						|
              {
 | 
						|
                handle = [
 | 
						|
                  {
 | 
						|
                    handler = "vars";
 | 
						|
                    # Grab the webroot out of the written config
 | 
						|
                    # The webroot is a symlinked combined Nextcloud directory
 | 
						|
                    root = config.services.nginx.virtualHosts.${config.services.nextcloud.hostName}.root;
 | 
						|
                  }
 | 
						|
                  {
 | 
						|
                    handler = "headers";
 | 
						|
                    response.set.Strict-Transport-Security = [ "max-age=31536000;" ];
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
              }
 | 
						|
              # Reroute carddav and caldav traffic
 | 
						|
              {
 | 
						|
                match = [
 | 
						|
                  {
 | 
						|
                    path = [
 | 
						|
                      "/.well-known/carddav"
 | 
						|
                      "/.well-known/caldav"
 | 
						|
                    ];
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
                handle = [
 | 
						|
                  {
 | 
						|
                    handler = "static_response";
 | 
						|
                    headers = {
 | 
						|
                      Location = [ "/remote.php/dav" ];
 | 
						|
                    };
 | 
						|
                    status_code = 301;
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
              }
 | 
						|
              # Block traffic to sensitive files
 | 
						|
              {
 | 
						|
                match = [
 | 
						|
                  {
 | 
						|
                    path = [
 | 
						|
                      "/.htaccess"
 | 
						|
                      "/data/*"
 | 
						|
                      "/config/*"
 | 
						|
                      "/db_structure"
 | 
						|
                      "/.xml"
 | 
						|
                      "/README"
 | 
						|
                      "/3rdparty/*"
 | 
						|
                      "/lib/*"
 | 
						|
                      "/templates/*"
 | 
						|
                      "/occ"
 | 
						|
                      "/console.php"
 | 
						|
                    ];
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
                handle = [
 | 
						|
                  {
 | 
						|
                    handler = "static_response";
 | 
						|
                    status_code = 404;
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
              }
 | 
						|
              # Redirect index.php to the homepage
 | 
						|
              {
 | 
						|
                match = [
 | 
						|
                  {
 | 
						|
                    file = {
 | 
						|
                      try_files = [ "{http.request.uri.path}/index.php" ];
 | 
						|
                    };
 | 
						|
                    not = [ { path = [ "*/" ]; } ];
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
                handle = [
 | 
						|
                  {
 | 
						|
                    handler = "static_response";
 | 
						|
                    headers = {
 | 
						|
                      Location = [ "{http.request.orig_uri.path}/" ];
 | 
						|
                    };
 | 
						|
                    status_code = 308;
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
              }
 | 
						|
              # Rewrite paths to be relative
 | 
						|
              {
 | 
						|
                match = [
 | 
						|
                  {
 | 
						|
                    file = {
 | 
						|
                      split_path = [ ".php" ];
 | 
						|
                      try_files = [
 | 
						|
                        "{http.request.uri.path}"
 | 
						|
                        "{http.request.uri.path}/index.php"
 | 
						|
                        "index.php"
 | 
						|
                      ];
 | 
						|
                    };
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
                handle = [
 | 
						|
                  {
 | 
						|
                    handler = "rewrite";
 | 
						|
                    uri = "{http.matchers.file.relative}";
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
              }
 | 
						|
              # Send all PHP traffic to Nextcloud PHP service
 | 
						|
              {
 | 
						|
                match = [ { path = [ "*.php" ]; } ];
 | 
						|
                handle = [
 | 
						|
                  {
 | 
						|
                    handler = "reverse_proxy";
 | 
						|
                    transport = {
 | 
						|
                      protocol = "fastcgi";
 | 
						|
                      split_path = [ ".php" ];
 | 
						|
                    };
 | 
						|
                    upstreams = [ { dial = "unix//run/phpfpm/nextcloud.sock"; } ];
 | 
						|
                  }
 | 
						|
                ];
 | 
						|
              }
 | 
						|
              # Finally, send the rest to the file server
 | 
						|
              { handle = [ { handler = "file_server"; } ]; }
 | 
						|
            ];
 | 
						|
          }
 | 
						|
        ];
 | 
						|
        terminal = true;
 | 
						|
      }
 | 
						|
    ];
 | 
						|
 | 
						|
    # Configure Cloudflare DNS to point to this machine
 | 
						|
    services.cloudflare-dyndns.domains = [ hostnames.content ];
 | 
						|
 | 
						|
    # Create credentials file for nextcloud
 | 
						|
    secrets.nextcloud = {
 | 
						|
      source = ./nextcloud.age;
 | 
						|
      dest = "${config.secretsDirectory}/nextcloud";
 | 
						|
      owner = "nextcloud";
 | 
						|
      group = "nextcloud";
 | 
						|
      permissions = "0440";
 | 
						|
    };
 | 
						|
    systemd.services.nextcloud-secret = {
 | 
						|
      requiredBy = [ "nextcloud-setup.service" ];
 | 
						|
      before = [ "nextcloud-setup.service" ];
 | 
						|
    };
 | 
						|
 | 
						|
    # Grant user access to Nextcloud directories
 | 
						|
    users.users.${username}.extraGroups = [ "nextcloud" ];
 | 
						|
 | 
						|
    # Open to groups, allowing for backups
 | 
						|
    systemd.services.phpfpm-nextcloud.serviceConfig.StateDirectoryMode = lib.mkForce "0770";
 | 
						|
 | 
						|
    # Log metrics to prometheus
 | 
						|
    networking.hosts."127.0.0.1" = [ hostnames.content ];
 | 
						|
    services.prometheus.exporters.nextcloud = {
 | 
						|
      enable = true;
 | 
						|
      username = config.services.nextcloud.config.adminuser;
 | 
						|
      url = "https://${hostnames.content}";
 | 
						|
      passwordFile = config.services.nextcloud.config.adminpassFile;
 | 
						|
    };
 | 
						|
    nmasur.presets.services.prometheus-exporters.scrapeTargets = [
 | 
						|
      "127.0.0.1:${builtins.toString config.services.prometheus.exporters.nextcloud.port}"
 | 
						|
    ];
 | 
						|
    # Allows nextcloud-exporter to read passwordFile
 | 
						|
    users.users.nextcloud-exporter.extraGroups =
 | 
						|
      lib.mkIf config.services.prometheus.exporters.nextcloud.enable
 | 
						|
        [ "nextcloud" ];
 | 
						|
  };
 | 
						|
}
 |