diff --git a/apps/base/nextcloud/database.yaml b/apps/base/nextcloud/database.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..dae30d6fad92f90ce2e9af2ec5a3d30b7b75aa1e
--- /dev/null
+++ b/apps/base/nextcloud/database.yaml
@@ -0,0 +1,18 @@
+apiVersion: "acid.zalan.do/v1"
+kind: postgresql
+metadata:
+  name: nextcloud-postgres
+  namespace: nextcloud
+spec:
+  teamId: "nextcloud"
+  volume:
+    size: 1Gi
+  numberOfInstances: 1
+  users:
+    nextcloud:
+    - superuser
+    - createdb
+  databases:
+    nextcloud: nextcloud
+  postgresql:
+    version: "14"
diff --git a/apps/base/nextcloud/kustomization.yaml b/apps/base/nextcloud/kustomization.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1d0c497be167e8a8e546abbfe3ef9e108f6eaf48
--- /dev/null
+++ b/apps/base/nextcloud/kustomization.yaml
@@ -0,0 +1,14 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+namespace: nextcloud
+resources:
+  - namespace.yaml
+  - database.yaml
+  - repository.yaml
+  - release.yaml
+  - ../../../shared/networkpolicies/allow-from-same-namespace.yaml
+  - ../../../shared/networkpolicies/allow-from-ingress.yaml
+  - ../../../shared/networkpolicies/allow-from-database.yaml
+  - ../../../shared/networkpolicies/allow-from-monitoring.yaml
+patchesStrategicMerge:
+  - networkpolicy.yaml
diff --git a/apps/base/nextcloud/namespace.yaml b/apps/base/nextcloud/namespace.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..243de68a6af1d522a010e971bd4832d81c9f1767
--- /dev/null
+++ b/apps/base/nextcloud/namespace.yaml
@@ -0,0 +1,36 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: nextcloud
+  labels:
+    name: nextcloud
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: nextcloud-reconciler
+  namespace: nextcloud
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: nextcloud-reconciler
+  namespace: nextcloud
+rules:
+  - apiGroups: ["*"]
+    resources: ["*"]
+    verbs: ["*"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: nextcloud-reconciler
+  namespace: nextcloud
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: nextcloud-reconciler
+subjects:
+  - kind: ServiceAccount
+    name: nextcloud-reconciler
+    namespace: nextcloud
diff --git a/apps/base/nextcloud/networkpolicy.yaml b/apps/base/nextcloud/networkpolicy.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ed15457db4e6635fb4d0b549ec6d6a4ec82517d6
--- /dev/null
+++ b/apps/base/nextcloud/networkpolicy.yaml
@@ -0,0 +1,20 @@
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: allow-from-ingress
+spec:
+  podSelector:
+    matchLabels:
+      app.kubernetes.io/name: nextcloud
+      app.kubernetes.io/component: app
+---
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: allow-from-monitoring
+spec:
+  podSelector:
+    matchLabels:
+      app.kubernetes.io/name: nextcloud
+      app.kubernetes.io/component: metrics
diff --git a/apps/base/nextcloud/release.yaml b/apps/base/nextcloud/release.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..982a159bd43421fb05664f161a2710e161fb5369
--- /dev/null
+++ b/apps/base/nextcloud/release.yaml
@@ -0,0 +1,140 @@
+apiVersion: helm.toolkit.fluxcd.io/v2beta1
+kind: HelmRelease
+metadata:
+  name: nextcloud
+  namespace: nextcloud
+spec:
+  serviceAccountName: nextcloud-reconciler
+  timeout: 5m
+  releaseName: nextcloud
+  chart:
+    spec:
+      chart: nextcloud
+      sourceRef:
+        kind: HelmRepository
+        name: nextcloud
+      version: 2.13.1
+  interval: 5m
+  valuesFrom:
+    - kind: ConfigMap
+      name: nextcloud-base-values
+      valuesKey: values.yaml
+    - kind: Secret
+      name: nextcloud-override-values
+      valuesKey: values-overrides.yaml
+      optional: true
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: nextcloud-base-values
+  namespace: nextcloud
+data:
+  values.yaml: |
+    nextcloud:
+      resources:
+        limits:
+          cpu: 1500m
+          memory: 2Gi
+        requests:
+          cpu: 500m
+          memory: 1Gi
+      strategy:
+        type: Recreate
+      extraSecurityContext:
+        runAsUser: "33"
+        runAsGroup: "33"
+        runAsNonRoot: true
+        readOnlyRootFilesystem: true
+      configs:
+        proxy.config.php: |-
+          <?php
+          $CONFIG = array (
+            'trusted_proxies' => array(
+              0 => '127.0.0.1',
+              1 => '10.0.0.0/8',
+            ),
+            'forwarded_for_headers' => array('HTTP_X_FORWARDED_FOR'),
+          );
+    internalDatabase:
+      enabled: false
+    externalDatabase:
+      enabled: true
+      type: postgresql
+      host: nextcloud-postgres
+      database: nextcloud
+      existingSecret:
+        enabled: true
+        secretName: nextcloud.nextcloud-postgres.credentials.postgresql.acid.zalan.do
+        usernameKey: username
+        passwordKey: password
+    cronjob:
+      enabled: true
+      failedJobsHistoryLimit: 1
+      successfulJobsHistoryLimit: 1
+      resources:
+        limits:
+          cpu: 100m
+          memory: 128Mi
+        requests:
+          cpu: 100m
+          memory: 128Mi
+    redis:
+      enabled: true
+    ingress:
+      annotations:
+        nginx.ingress.kubernetes.io/proxy-body-size: 4G
+        nginx.ingress.kubernetes.io/server-snippet: |-
+          server_tokens off;
+          proxy_hide_header X-Powered-By;
+
+          rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
+          rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
+          rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json;
+          location = /.well-known/carddav {
+            return 301 $scheme://$host/remote.php/dav;
+          }
+          location = /.well-known/caldav {
+            return 301 $scheme://$host/remote.php/dav;
+          }
+          location = /robots.txt {
+            allow all;
+            log_not_found off;
+            access_log off;
+          }
+          location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
+            deny all;
+          }
+          location ~ ^/(?:autotest|occ|issue|indie|db_|console) {
+            deny all;
+          }
+    persistence:
+      enabled: true
+    resources:
+      limits:
+        cpu: 1500m
+        memory: 2Gi
+      requests:
+        cpu: 500m
+        memory: 1Gi
+    extraSecurityContext:
+      runAsUser: "33"
+      runAsGroup: "33"
+      runAsNonRoot: true
+      readOnlyRootFilesystem: true
+    metrics:
+      enabled: true
+      resources:
+        limits:
+          cpu: 100m
+          memory: 128Mi
+        requests:
+          cpu: 100m
+          memory: 128Mi
+    rbac:
+      enabled: true
+      serviceaccount:
+        create: true
+        name: nextcloud-serviceaccount
+    startupProbe:
+      enabled: true
diff --git a/apps/base/nextcloud/repository.yaml b/apps/base/nextcloud/repository.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..902fb283386f917bc5953572d39c603ebfd8afa9
--- /dev/null
+++ b/apps/base/nextcloud/repository.yaml
@@ -0,0 +1,8 @@
+apiVersion: source.toolkit.fluxcd.io/v1beta1
+kind: HelmRepository
+metadata:
+  name: nextcloud
+  namespace: nextcloud
+spec:
+  interval: 30m
+  url: https://nextcloud.github.io/helm/
diff --git a/apps/k8s01/nextcloud/certificate.yaml b/apps/k8s01/nextcloud/certificate.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d20d2d454b97db00cf98c9f535de87437781b99b
--- /dev/null
+++ b/apps/k8s01/nextcloud/certificate.yaml
@@ -0,0 +1,64 @@
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+    name: nextcloud-tls
+    namespace: matrix
+spec:
+    dnsNames:
+        - ENC[AES256_GCM,data:RElY5ezZBbNniLIQfaYghe+52yeisRt0qA==,iv:ex3kHYJ82sf8SFXROqsRXUZ4uv9w/5Om1dgOtz6BD4E=,tag:CrhP+VkHt/e3koa1Sy9XFw==,type:str]
+    issuerRef:
+        name: letsencrypt
+        kind: ClusterIssuer
+    secretName: ingress-nextcloud-tls
+sops:
+    kms: []
+    gcp_kms: []
+    azure_kv: []
+    hc_vault: []
+    age: []
+    lastmodified: "2022-03-22T22:25:36Z"
+    mac: ENC[AES256_GCM,data:kgqzgq6ZfWr9bEDT7DMtQzpEekwhpHiBNWH6484z1lUppL9rE6Tb0EcDPRl52B61R8JmFrQgiV7XMa+kNwNN1ra0w4M4xaxJu9Q9icMknsv6pB6VvjaLoVzRENfYNnWSrXrerHaL+nxpSgH6S8P7iVg1X15cSsU+rytXDADrAjM=,iv:s1hC2IM/PL0DkjhahGQrcmRTeOd20N+4RWVMEkB0rUA=,tag:xalgMPonrELvkSgrN4AxSw==,type:str]
+    pgp:
+        - created_at: "2022-01-21T18:13:48Z"
+          enc: |-
+            -----BEGIN PGP MESSAGE-----
+
+            wcFMA7kpg2bgzVHcARAAHhDshl1OJqNRUolNvbIXzOuDzssJnvyi6cIZuMmVMsxf
+            a6wAWAtYOehvtn1ODL7/h4fIpBtfp7d8VuwfJSrh3ghUeiOl3zRzQbmaFA2L5/iG
+            Jd94tFAVwIl30qjcYqGVB2RF27VF1RElzgDLQh3hiXn1hDC+WmNSnBF5hwnwCFOL
+            wM4BHuE2AB4TX3PlYSo1n71VSzcCqRzbIxelZasYLnJQVL0VE6AjEd/fHS468R8N
+            aZ3mhmHW3sWzuLHNREMD2Q3ghkguLhau0VoETlYRI9103I4k7/khFrhAj5l2/PUr
+            2SWgpXyRqXVaKPeTiQs3QR8B5jNq3BlZj6Celw5Ig/wx3LY0EhI9e9WFgtSlZxM+
+            2yk65HQGvTIgsbys/z/0skA9vqik9csFRsH9iK42E/+XLvoAT6yxyl0cv1kBEyAS
+            ggPmKOq8+CT+voHzuh8kZHq9Sa8kH5xL1DQLzX2yIruV3OhTPSK+VlDpjUbycmI2
+            qR1oCo/snOJwwwvfl9vu0B8FCwhrz8554ZQBErFfJl6GFiUV8LElRlZh5S9Jiysr
+            nYJS5gxrcvjF/0Y6EHEfWDRDxvCHoWQpWhl2hRkh5UlQKH0ab+QWLYpISyNJxjfl
+            orQJdaVX3BQwhqMLwiMLGoaNGrSpmxXveLOZmsdK0obXC67lyE6ZM/Wy6gx2dFnS
+            5gFdXCLzQmmjYK8gIlsejQdnxZI2qWavZIN9T70OZQGaDE/S+U1uxKjuGBM7HTcP
+            7f1nUa6z96A9ydWs1xHjtm7k172V16PMSrvjQ8KLhFJd9eJDq3ksAA==
+            =XgF6
+            -----END PGP MESSAGE-----
+          fp: 286791FB6648539775DB31B8FCB98C2A3EC6F601
+        - created_at: "2022-01-21T18:13:48Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQIMA4oYbIHZIrAPAQ//S/9rOkbd3beNH20dxgZ7VuZxgnjiV3Hd3om717njcMm2
+            kCfTJ3AmpLtQsT2s1W221tIyCwtHOobj82ANP9KzNi4e6v3LlNTIVHTQiHXk9KJP
+            AX6JoCOLu3bAI0xcdApNBU2wAlHBVC+T4BUfhPqD5AdHpW++e1qUIsM/6TViunHj
+            BWoIA0bpXqyOhTm1GbkJrHMgczJn2qgR5lBf8wgGmASd8jlNyfA7SxoKHj8sl/Ji
+            nucP/90dmyD2eBIJYdYS3anJYa2uP96oioG5xxIyfppnL5dwozDAit3Z5vvnBZNb
+            1rrpUnN8H0cCcaj7tmDEmjGfjGwxLKegQRZX7Pg5hwaaOOPGheXf8Ip/DpDf6T0n
+            Sq24X6DC5gD1RBU+YY6ZayMt/OKpVVVwRlY4BTDIUe4M+ecK/fve5vpDW2M+KWMc
+            pOkO1B09/prsX0w5XjFh8hb/6HlDDhomiB+BszcRCUDzocRzSEIFwMf7/iTaExe8
+            2fKCCHB4kHo6GHpydlQOpnGMOvDmiNKopXxTkFQUFQjyRmHGXf/u79JNXBjHkniv
+            ZiokjTEarwMp68dyiaL4L/5Uk+4NG3MetobqSaeW2TbeBwif3G2eFleYscz7QPIR
+            5ZBBhU/CoUEz2Xge6t8rlp8PNcQ1yq/R+tZjaeqIIT4++ZxCErhA0lsxyFrgLefU
+            aAEJAhD7hR3IMDGN2zOZSiw1IBz9P8Jss/oERQiuVpe/eTv5Vqj9vuL+koKftwnF
+            vSVkNo0fLwNLtnU659Mkoj9utoUL9tAhcCMpP3NehKkBG5RjF9crnIP6zT3lvVU0
+            GYyW4Lsfrt/a
+            =FfV+
+            -----END PGP MESSAGE-----
+          fp: B137EE1549DFAF960DD1E2B15147025FB9F09E07
+    encrypted_regex: ^(data|stringData|email|dnsZones?|dnsNames?|hosts?|tang|externalURL)$
+    version: 3.7.1
diff --git a/apps/k8s01/nextcloud/kustomization.yaml b/apps/k8s01/nextcloud/kustomization.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a946a872a8c2c61aff26fa5182dc0ad46d572b2e
--- /dev/null
+++ b/apps/k8s01/nextcloud/kustomization.yaml
@@ -0,0 +1,6 @@
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+resources:
+  - ../../base/nextcloud
+  - certificate.yaml
+  - nextcloud-values.yaml
diff --git a/apps/k8s01/nextcloud/nextcloud-values.yaml b/apps/k8s01/nextcloud/nextcloud-values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..68fdc92d478cbcd6452f7fe200b8ba70d4663784
--- /dev/null
+++ b/apps/k8s01/nextcloud/nextcloud-values.yaml
@@ -0,0 +1,60 @@
+apiVersion: v1
+kind: Secret
+metadata:
+    name: nextcloud-override-values
+    namespace: nextcloud
+type: Opaque
+stringData:
+    values-overrides.yaml: ENC[AES256_GCM,data:TUfQKjLFRkbbiDiMNQQ6dZcZU9li17ra6qVmplN2vAzejBfXVBSpf6hfFE0PYnpqKd4zMBJYk5wf2xfYgfORjRJjE9MiYDctbvQslx9NYXXOAw7xabFDbCh/9hx7TLWQD4ZXB0/vRUHlfMnNSNH28kKS1eUNMKlxJbv3XePhnIB3w2cT4JB9f0fXFgxnA1F4ZAQ1v1TxOC8aSMjsT2OFGNb+u8yz38PIUo87jAWTxE59K5KjSnhNM8e6y2UHef1qr1rSbJ7oQS5aVTeJmdPFXJ/V2VyGpyg1Y7ngh2K3o1B9uS7JHxcKfmhbd119kJYkUh/4rbUdUHTv2o6LYnF2gAppdWBUWslcKnbc/1/M/TjRzJ1Nc9BEYw2FWPj3CtaaBC0qsvyjN6n9FMGqvann48NP9BD+WGqf7vg1AMvQw46H7rc3B8kgJr1vEFYLIr8PDz2NhDCUKvE+TA0LDtlfcTFscAT4wgOcm4/fP+eXATxSe5XOj2GG62/IGPYfeb/BeAxn0TWpUwY80K1r2DGPVNeigASjxr+hIOClC2IIW/I0nPx0FnTuTUfhzGQN32nuh19Zb7eTH2+ABfUK4Flz18Di3ubuNjJ4PnKC9WVHCKgLHj1eeeiMCDsRS0cFNP0wIN4CnzSe9bhVCVncLgUc4YB3DBjKnIKGG+ZOMYNGXEYVUHiJpvKy0kqcCQU=,iv:Q83hx2sWHstGqAYAU8i6VByrCYFVvjm8LK4eM5Swt/Y=,tag:4XkT3tqNsfyjONY6S63Jvg==,type:str]
+sops:
+    kms: []
+    gcp_kms: []
+    azure_kv: []
+    hc_vault: []
+    age: []
+    lastmodified: "2022-03-22T22:49:31Z"
+    mac: ENC[AES256_GCM,data:dGO3FR97WkFYTKhBQIKCxc7I9Z10gweFcoFOo8jHik5s1XeE2jZtqEc2QsUGDLTun8bFoLqORBZC6c7aB+1l3nrqqHjvVbUua9ShvQnZAAnAQT5ef09fthFk5vhElFmhXEuGQRZoAImuje2jjdFHGmfr1K2SWorWEiSZFKdgLuQ=,iv:Vl+f2Kru5Pzqq+h8a7wIgLYLl1cKU3G926U6KcyHvHA=,tag:gNYEbhD5Hu/RDs9WupPMfA==,type:str]
+    pgp:
+        - created_at: "2022-03-22T22:26:35Z"
+          enc: |-
+            -----BEGIN PGP MESSAGE-----
+
+            wcFMA7kpg2bgzVHcARAApcdDAfEgx93xGtkm4f7xTuRhvUyl8lw85rIHbWcAveYU
+            ayU88OLaoQyeZDZkOXbtxMHpry8GbId6vPAJ7KflT2eMP0A4uQGSSCQO6+5QcaYg
+            sbO/zT4vdprN7icLbvmmoK2Dh+hOo5Z7/7YGmdJfaaATzT2BGL/cVS1bonI83vXR
+            lzlW/DglIe7oNEKGVT5vWR5uGvq/dJwSRe/34eutEnJuV30imxHOcpxy3uXJFFXJ
+            3eKTk8dNLz3UE3IeUjbFdPFZYU+grOAOOCZRK0IOYFn+SF7E3dewgiwEdaXzz3gK
+            /6aEMEmf5vyVqn9jOaqZhKRqE7tW5HnhwIIlxcMPhkLVZvYf4F2EDA5f12C2hdp0
+            s7fFhU7v5GgFaHMJuaWVPxDnWTrNIst9bgeJv/N4RVfrLifrZJcqa9lE8ou0iCr5
+            dLi9d6UjsgWAREIViz+Uz7dJQ9QeJ6PGYgg/xgf0ihJFG7sx+TBG58DKb3G3tyUV
+            8hfK8Ou9m+zYnd13mJ2mV3rY0rmXusT+NcqTG2G4bBG5NimGpJS3rO7tAjjp/8sN
+            hMM46ay0vVTUXx1FwmjUFDG1e4sc7fKxTaCBizMjeUfZpAOiy/10YQmrFHBsftpo
+            K5j0nFMoG9NeO+2ffEmLhRtxvMe3WpINk7du3F624rYIGCB0aNUP69FCeJKuUQHS
+            5gH5AwnxOAtQakDksfLxJhUG1NlaS0iAFkZkTTibvOJwsY9L/scDDQlseb5zBKaZ
+            sOPwmn6hL4KavxF9BPG33ILkZKbkcvlaTlAMMY3iBs+MZeIB4+i/AA==
+            =SQqg
+            -----END PGP MESSAGE-----
+          fp: 286791FB6648539775DB31B8FCB98C2A3EC6F601
+        - created_at: "2022-03-22T22:26:35Z"
+          enc: |
+            -----BEGIN PGP MESSAGE-----
+
+            hQIMA4oYbIHZIrAPAQ//fGGoDT5KfsG/o6r5xhDHSc0IFH6zT2TFIB6TuA5SwHfV
+            8t3IeKD0bE//4f8AxGAVocw+AetolwrQL/Tl+n0UV9P44Jeh5VlCAGltHcowR53o
+            zdjS3+i9K3OOvQFhF+aYrPcnc+aTn9KbptHCam0w+Lr2UkYSAPAZHsBcoMp24mHX
+            6A+5kP1kaRzFzEn4TCNeTt13W1AsJIoSagkBWfYRBkRPk1OzGOuYqX6yeqj7a0kM
+            8uiloTQgWOiBSOyRtxUJi87CTrMXyb0F2E9HMyhgRnzF0YX0ZU0UVG8MNdRL8eFD
+            WYY68OK7DQw3zlJubscYQ2jltxKcq5g9qUCw/sXaNurtohIx9UeaHtfp036EMb22
+            5StgGEnBirUzfSrQGT3kuj20lcMtQAr/d1UsmQNjB36eOZSrx0m80pO8JVYL62/O
+            HLYnAHU52aAPtE7brNEVg4yRLCbWyVY3Z3H9OaTVXwNIMFoMEgkHHnNlsb+1ZnhV
+            cStKMO3H6W8eXQi3VGIVNhuC1ltsxHQL1I22Kr41JEnuaB9Jy5bsEbrO4XGyDdte
+            hMI8Gx+0KZAMlKuZKLS6sMa4oVnQTy8w20PtVrrS0zDrQRPpxBrOgzjrNeMj9FpS
+            q/efiCAOBc8eVd8N/7j66UItwrysfmIfsHWfoPotS7F6WmUHeAyoWjfcvTZyd4bU
+            ZgEJAhAtdCnHNvUSl5O9XZuSu51pRwj+O72kZXRSJWv7GTT9dsRfuM5Dy9A/tuVI
+            BuZraI4JyAWb2KbkM6onp3Rh9IcLuzqEYm/ETktxTtO1HlcVPJ2NMcFgTCzaIGX9
+            +rtkG7tPbA==
+            =tvBa
+            -----END PGP MESSAGE-----
+          fp: B137EE1549DFAF960DD1E2B15147025FB9F09E07
+    encrypted_regex: ^(data|stringData|email|dnsZones?|dnsNames?|hosts?|tang|externalURL|.*-secret|.*-url|.*Secrets?|.*-domain|password|subjects|node|apiURL|.*(S|s)erverNames?|.*SecretKey)$
+    version: 3.7.1