Merge "Add nextcloud" into main
diff --git a/flake.nix b/flake.nix
index 838808d..3022dc2 100644
--- a/flake.nix
+++ b/flake.nix
@@ -66,6 +66,7 @@
               ./modules/loginctl-linger.nix
               ./modules/matrix.nix
               ./modules/mongodb.nix
+              ./modules/nextcloud.nix
               ./modules/node.nix
               ./modules/postgres.nix
               ./modules/privatebin.nix
diff --git a/modules/caddy.nix b/modules/caddy.nix
index eddcf80..26e0a58 100644
--- a/modules/caddy.nix
+++ b/modules/caddy.nix
@@ -1,5 +1,6 @@
 { base, config, pkgs, lib, ... }: lib.recursiveUpdate
 {
+  services.nginx.enable = false; # PrivateBin, nextcloud etc. attempts to enable nginx but we already use caddy
   services.caddy.enable = true;
   services.caddy.configFile = lib.pipe ./caddy/caddyfile.nix [
     import
diff --git a/modules/caddy/caddyfile.nix b/modules/caddy/caddyfile.nix
index 0b2acf4..4924c6f 100644
--- a/modules/caddy/caddyfile.nix
+++ b/modules/caddy/caddyfile.nix
@@ -382,6 +382,11 @@
             "${pkgs.privatebin}/share/privatebin"
             "unix/${config.services.phpfpm.pools.privatebin.socket}"
           )
+          (PHPRoute
+            [ "cloud.clicks.codes" "nextcloud.clicks.codes" "docs.clicks.codes" ]
+            "${config.services.nextcloud.package}"
+            "unix/${config.services.phpfpm.pools.nextcloud.socket}"
+          )
         ];
       };
       srv1 = {
diff --git a/modules/nextcloud.nix b/modules/nextcloud.nix
new file mode 100644
index 0000000..9605bfc
--- /dev/null
+++ b/modules/nextcloud.nix
@@ -0,0 +1,48 @@
+{config, pkgs, lib, ...}: {
+    sops.secrets.clicks_nextcloud_db_password = {
+        mode = lib.mkForce "0440";
+        group = lib.mkForce "nextcloud";
+    };
+
+    users.users.nextcloud = {
+        isSystemUser = true;
+        createHome = true;
+        home = "/var/lib/nextcloud";
+        group = config.users.groups.nextcloud.name;
+        shell = pkgs.bashInteractive;
+    };
+    users.groups.nextcloud = {};
+
+
+    services.nextcloud.enable = true;
+    services.nextcloud.config.adminpassFile = config.sops.secrets.nextcloud_admin_password.path;
+    services.nextcloud.hostName = "cloud.clicks.codes";
+    services.nextcloud.package = pkgs.nextcloud27;
+    services.nextcloud.poolSettings = {
+        pm = "dynamic";
+        "pm.max_children" = "32";
+        "pm.max_requests" = "500";
+        "pm.max_spare_servers" = "4";
+        "pm.min_spare_servers" = "2";
+        "pm.start_servers" = "2";
+        "listen.owner" = config.users.users.nextcloud.name;
+        "listen.group" = config.users.users.nextcloud.group;
+    };
+
+    services.nextcloud.config = {
+        dbtype = "pgsql";
+        dbport = config.services.postgresql.port;
+        dbpassFile = config.sops.secrets.clicks_nextcloud_db_password.path;
+        dbname = "nextcloud";
+        dbhost = "localhost";
+        extraTrustedDomains = [ "nextcloud.clicks.codes" "docs.clicks.codes" ];
+    };
+
+    sops.secrets.nextcloud_admin_password = {
+        mode = "0600";
+        owner = config.users.users.nextcloud.name;
+        group = config.users.users.nextcloud.group;
+        sopsFile = ../secrets/nextcloud.json;
+        format = "json";
+    };
+}
\ No newline at end of file
diff --git a/modules/postgres.nix b/modules/postgres.nix
index d2844c1..cedb222 100644
--- a/modules/postgres.nix
+++ b/modules/postgres.nix
@@ -14,6 +14,7 @@
       "vaultwarden"
       "privatebin"
       "keycloak"
+      "nextcloud"
     ];
 
     ensureUsers = [
@@ -48,6 +49,12 @@
           "DATABASE privatebin" = "ALL PRIVILEGES";
         };
       }
+      {
+        name = "nextcloud";
+        ensurePermissions = {
+          "DATABASE nextcloud" = "ALL PRIVILEGES";
+        };
+      }
     ] ++ (map
       (name: (
         {
@@ -82,6 +89,7 @@
       { user = "keycloak"; passwordFile = config.sops.secrets.clicks_keycloak_db_password.path; }
       { user = "vaultwarden"; passwordFile = config.sops.secrets.clicks_bitwarden_db_password.path; }
       { user = "privatebin"; passwordFile = config.sops.secrets.clicks_privatebin_db_password.path; }
+      { user = "nextcloud"; passwordFile = config.sops.secrets.clicks_nextcloud_db_password.path; }
     ] [
       (map (userData: ''
         $PSQL -tAc "ALTER USER ${userData.user} PASSWORD '$(cat ${userData.passwordFile})';"
@@ -95,6 +103,7 @@
     "clicks_keycloak_db_password"
     "clicks_bitwarden_db_password"
     "clicks_privatebin_db_password"
+    "clicks_nextcloud_db_password"
   ] [
     (map (name: {
       inherit name;
diff --git a/modules/privatebin.nix b/modules/privatebin.nix
index 5dd6a28..e82c389 100644
--- a/modules/privatebin.nix
+++ b/modules/privatebin.nix
@@ -1,7 +1,6 @@
 { config, lib, base, ... }:
 lib.recursiveUpdate
 {
-  services.nginx.enable = false; # PrivateBin attempts to enable nginx but we already use caddy
   services.privatebin = {
     enable = true;
     settings = {
@@ -17,7 +16,7 @@
 
         info = ''Powered by <a href="https://privatebin.info/">PrivateBin</a>. Provided as a service free-of-charge by Clicks. Come chat with us <a href="https://matrix.to/#/#global:coded.codes"> on Matrix</a>'';
         notice = "This service has no guarantee of uptime, and pastes are not backed up. If you need somewhere to host the last words of your wise old grandfather for time immemorial this is not the place.";
-        
+
         langaugeselection = true;
       };
 
diff --git a/modules/syncthing.nix b/modules/syncthing.nix
index d9f482c..cea1012 100644
--- a/modules/syncthing.nix
+++ b/modules/syncthing.nix
@@ -1,6 +1,4 @@
 { pkgs, ... }: {
-  environment.systemPackages = with pkgs; [ syncthing ];
-
   services.syncthing.enable = true;
   services.syncthing.openDefaultPorts = true;
 
diff --git a/secrets/nextcloud.json b/secrets/nextcloud.json
new file mode 100644
index 0000000..e31d61d
--- /dev/null
+++ b/secrets/nextcloud.json
@@ -0,0 +1,28 @@
+{
+	"nextcloud_admin_password": "ENC[AES256_GCM,data:fVg/Kt+oQBWSAwTT+j4RZNimMZSXfoxD4oNOosFy6F1+YIFVuxajmm05k2FHS9cUcmHcpF1oqoBrroLgMvWVGn7ZkFOa26KwT7Is3IOlnsNaL96dsLh1biYw4dCSftfbPvIiWdS1lZnqXWU99/yleq3qpS9qcb8tNq2TCHecZco=,iv:VMEoabNI5lGum+pFW93JHa9+C0OGZMxnG4J4/15D5No=,tag:E5eOVADG8EwH3WM5oh1hig==,type:str]",
+	"sops": {
+		"kms": null,
+		"gcp_kms": null,
+		"azure_kv": null,
+		"hc_vault": null,
+		"age": [
+			{
+				"recipient": "age15mv77dpnh5762gk5rsw2u79uza4tg8cu6r3nlwjudlzmdqqck3ss6mg9dy",
+				"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4T2dxSmN3YkxzZGthaHpR\ndVN6NWtPcGFmMlBwcjJKWG94Yjk2eTR2VHhvCmc5YXJlSUdxOFJVdm0yVmlsSDc4\ndjlXL3h0eHFhUml5bEYyT003cnFVTWMKLS0tIEE4dzllVzlsWjhFbFBhWElrZEJP\nazBneU0rYTFlTCtiZW9RU09hZnZua3MKl4ubpy7xRx4BCQ6A1SawLKMNID9Xd3N2\nhctRsfaMISWwFnw8yOO14zT02bxXXy1NS8vpQSQyuybv++FoUAklxQ==\n-----END AGE ENCRYPTED FILE-----\n"
+			},
+			{
+				"recipient": "age1m7k864feyuezllp2hj4edkccn36rthrvfw969j6f0l3c0mhh5emsnfx6pd",
+				"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBScytCcHJXM2dzTlA1bW4w\nLzhvOXNxSkpVeTJHN2JERWgyNEw0US9ibVQ0CjB4d09mclFhVkxJYmVjZk56REY3\nY1lpNnJvakFqamhwM3lKeiszSkV1YUUKLS0tIGM1SnlCWGFpL1BjMk01Tllmb3BI\ncUc5Y0xWbnJvZVFpZlBjT3BzZnFvN28KBB/erTTzn44j1dLHqXOg9KmH7srvoDIW\n105QKYsU40h2qtROVscxB5vcpPjxgcacsHFi89wRhUqy1n45nAkNhg==\n-----END AGE ENCRYPTED FILE-----\n"
+			},
+			{
+				"recipient": "age1fxxnmkeuqhhct93c43pwkzhuzzq8857s5hye6pgfpku70kjn4ecqtamfqr",
+				"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4dTZWN0wreHAzNGFlTVJo\nZnAxZ3ZQYzFHTGdTUVNnVmVuS1I4YVZqRENvClY3QzVaZGwxRVk1c0JrbDhObzF1\nMFErbFpmMFBpYWhZK3N0ZGtkeklMcm8KLS0tIEpNUFNqa0RRV3RiUnRjTXN6ZnVa\nLzBOenFydE4vSkdQZ0FpamY4VC95THMK796rEHXR0K1VrNZofw7nk6SlvJx9cQcU\nswcrNrGBSrSO2mOX+fRKqBMfP0BMsCdk/jmdwl/RjTqPPQI4/hwaTw==\n-----END AGE ENCRYPTED FILE-----\n"
+			}
+		],
+		"lastmodified": "2023-10-07T21:36:03Z",
+		"mac": "ENC[AES256_GCM,data:w4wB57MrB/1h36VBK6wjG9RbUVf+MUlJyUnkBo83isBnMROZb8SOab3DcUQLl0hysCvvMnSuiLg/OCKi/w2cLGsYb+NELJ9oW02BoEv7SPymfCznmn37l9Tk8ri10V8LJ7hXVp9brJWyIA8HTwcr6EhNJMWhXyiZwQEMwppycHU=,iv:BI6f001a9fXRuVVXUcU8tc3Lb9J5rNV/HInauLMF5o8=,tag:ZzZSqo9iKWyKVDyghq7ORw==,type:str]",
+		"pgp": null,
+		"unencrypted_suffix": "_unencrypted",
+		"version": "3.7.3"
+	}
+}
\ No newline at end of file