diff --git a/public/index.html b/public/index.html
deleted file mode 100644
index 0f0d145..0000000
--- a/public/index.html
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
- c4k-keycloak
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/test/cljc/dda/c4k_nextcloud/backup_test.cljc b/src/test/cljc/dda/c4k_nextcloud/backup_test.cljc
new file mode 100644
index 0000000..d9b5f38
--- /dev/null
+++ b/src/test/cljc/dda/c4k_nextcloud/backup_test.cljc
@@ -0,0 +1,93 @@
+(ns dda.c4k-nextcloud.backup-test
+ (:require
+ #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
+ :cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
+ [dda.c4k-nextcloud.backup :as cut]))
+
+
+(deftest should-generate-secret
+ (is (= {:apiVersion "v1"
+ :kind "Secret"
+ :metadata {:name "backup-secret"}
+ :type "Opaque"
+ :data
+ {:aws-access-key-id "YXdzLWlk", :aws-secret-access-key "YXdzLXNlY3JldA==", :restic-password "cmVzdGljLXB3"}}
+ (cut/generate-secret {:aws-access-key-id "aws-id" :aws-secret-access-key "aws-secret" :restic-password "restic-pw"}))))
+
+(deftest should-generate-config
+ (is (= {:apiVersion "v1"
+ :kind "ConfigMap"
+ :metadata {:name "backup-config"
+ :labels {:app.kubernetes.io/name "backup"
+ :app.kubernetes.io/part-of "cloud"}}
+ :data
+ {:restic-repository "s3:restic-repository"}}
+ (cut/generate-config {:restic-repository "s3:restic-repository"}))))
+
+(deftest should-generate-cron
+ (is (= {:apiVersion "batch/v1beta1"
+ :kind "CronJob"
+ :metadata {:name "nextcloud-backup"
+ :labels {:app.kubernetes.part-of "cloud"}}
+ :spec {:schedule "10 23 * * *"
+ :successfulJobsHistoryLimit 1
+ :failedJobsHistoryLimit 1
+ :jobTemplate
+ {:spec
+ {:template
+ {:spec
+ {:containers
+ [{:name "backup-app"
+ :image "domaindrivenarchitecture/c4k-nextcloud-backup"
+ :imagePullPolicy "IfNotPresent"
+ :command ["/entrypoint.sh"]
+ :env
+ [{:name "POSTGRES_USER"
+ :valueFrom
+ {:secretKeyRef
+ {:name "postgres-secret"
+ :key "postgres-user"}}}
+ {:name "POSTGRES_PASSWORD"
+ :valueFrom
+ {:secretKeyRef
+ {:name "postgres-secret"
+ :key "postgres-password"}}}
+ {:name "POSTGRES_DB"
+ :valueFrom
+ {:configMapKeyRef
+ {:name "postgres-config"
+ :key "postgres-db"}}}
+ {:name "POSTGRES_HOST"
+ :value "postgresql-service:5432"}
+ {:name "POSTGRES_SERVICE"
+ :value "postgresql-service"}
+ {:name "POSTGRES_PORT"
+ :value "5432"}
+ {:name "AWS_DEFAULT_REGION"
+ :value "eu-central-1"}
+ {:name "AWS_ACCESS_KEY_ID_FILE"
+ :value "/var/run/secrets/backup-secrets/aws-access-key-id"}
+ {:name "AWS_SECRET_ACCESS_KEY_FILE"
+ :value "/var/run/secrets/backup-secrets/aws-secret-access-key"}
+ {:name "RESTIC_REPOSITORY"
+ :valueFrom
+ {:configMapKeyRef
+ {:name "backup-config"
+ :key "restic-repository"}}}
+ {:name "RESTIC_PASSWORD_FILE"
+ :value "/var/run/secrets/backup-secrets/restic-password"}]
+ :volumeMounts
+ [{:name "nextcloud-data-volume"
+ :mountPath "/var/backups"}
+ {:name "backup-secret-volume"
+ :mountPath "/var/run/secrets/backup-secrets"
+ :readOnly true}]}]
+ :volumes
+ [{:name "nextcloud-data-volume"
+ :persistentVolumeClaim
+ {:claimName "nextcloud-pvc"}}
+ {:name "backup-secret-volume"
+ :secret
+ {:secretName "backup-secret"}}]
+ :restartPolicy "OnFailure"}}}}}}
+ (cut/generate-cron))))
diff --git a/src/test/cljc/dda/c4k_nextcloud/core_test.cljc b/src/test/cljc/dda/c4k_nextcloud/core_test.cljc
new file mode 100644
index 0000000..c841770
--- /dev/null
+++ b/src/test/cljc/dda/c4k_nextcloud/core_test.cljc
@@ -0,0 +1,35 @@
+(ns dda.c4k-nextcloud.core-test
+ (:require
+ #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
+ :cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
+ [dda.c4k-nextcloud.core :as cut]))
+
+(deftest should-k8s-objects
+ (is (= 16
+ (count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
+ :postgres-db-user "nextcloud"
+ :postgres-db-password "nextcloud-db-password"
+ :issuer :prod
+ :nextcloud-data-volume-path "/var/nextcloud"
+ :postgres-data-volume-path "/var/postgres"
+ :aws-access-key-id "aws-id"
+ :aws-secret-access-key "aws-secret"
+ :restic-password "restic-pw"
+ :restic-repository "restic-repository"}))))
+ (is (= 14
+ (count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
+ :postgres-db-user "nextcloud"
+ :postgres-db-password "nextcloud-db-password"
+ :issuer :prod
+ :aws-access-key-id "aws-id"
+ :aws-secret-access-key "aws-secret"
+ :restic-password "restic-pw"
+ :restic-repository "restic-repository"}))))
+ (is (= 11
+ (count (cut/k8s-objects {:fqdn "nextcloud-neu.prod.meissa-gmbh.de"
+ :postgres-db-user "nextcloud"
+ :postgres-db-password "nextcloud-db-password"
+ :issuer :prod
+ :aws-access-key-id "aws-id"
+ :aws-secret-access-key "aws-secret"
+ :restic-password "restic-pw"})))))
diff --git a/src/test/cljc/dda/c4k_nextcloud/nextcloud_test.cljc b/src/test/cljc/dda/c4k_nextcloud/nextcloud_test.cljc
new file mode 100644
index 0000000..b48bd0f
--- /dev/null
+++ b/src/test/cljc/dda/c4k_nextcloud/nextcloud_test.cljc
@@ -0,0 +1,81 @@
+(ns dda.c4k-nextcloud.nextcloud-test
+ (:require
+ #?(:clj [clojure.test :refer [deftest is are testing run-tests]]
+ :cljs [cljs.test :refer-macros [deftest is are testing run-tests]])
+ [dda.c4k-nextcloud.nextcloud :as cut]))
+
+(deftest should-generate-certificate
+ (is (= {:apiVersion "cert-manager.io/v1alpha2"
+ :kind "Certificate"
+ :metadata {:name "cloud-cert", :namespace "default"}
+ :spec
+ {:secretName "cloud-secret"
+ :commonName "xx"
+ :dnsNames ["xx"]
+ :issuerRef
+ {:name "letsencrypt-prod-issuer", :kind "ClusterIssuer"}}}
+ (cut/generate-certificate {:fqdn "xx" :issuer :prod}))))
+
+(deftest should-generate-ingress
+ (is (= {:apiVersion "extensions/v1beta1"
+ :kind "Ingress"
+ :metadata
+ {:name "ingress-cloud"
+ :annotations
+ {:cert-manager.io/cluster-issuer
+ "letsencrypt-staging-issuer"
+ :nginx.ingress.kubernetes.io/proxy-body-size "256m"
+ :nginx.ingress.kubernetes.io/ssl-redirect "true"
+ :nginx.ingress.kubernetes.io/rewrite-target "/"
+ :nginx.ingress.kubernetes.io/proxy-connect-timeout "300"
+ :nginx.ingress.kubernetes.io/proxy-send-timeout "300"
+ :nginx.ingress.kubernetes.io/proxy-read-timeout "300"}
+ :namespace "default"}
+ :spec
+ {:tls [{:hosts ["xx"], :secretName "nextcloud-secret"}]
+ :rules
+ [{:host "xx"
+ :http
+ {:paths
+ [{:path "/"
+ :backend
+ {:serviceName "nextcloud-service", :servicePort 80}}]}}]}}
+ (cut/generate-ingress {:fqdn "xx"}))))
+
+(deftest should-generate-persistent-volume
+ (is (= {:kind "PersistentVolume"
+ :apiVersion "v1"
+ :metadata {:name "cloud-pv-volume", :labels {:type "local" :app "cloud"}}
+ :spec
+ {:storageClassName "manual"
+ :accessModes ["ReadWriteOnce"]
+ :capacity {:storage "200Gi"}
+ :hostPath {:path "xx"}}}
+ (cut/generate-persistent-volume {:nextcloud-data-volume-path "xx"}))))
+
+(deftest should-generate-deployment
+ (is (= {:containers
+ [{:image "domaindrivenarchitecture/meissa-cloud-app"
+ :name "cloud-app"
+ :imagePullPolicy "IfNotPresent"
+ :ports [{:containerPort 80}]
+ :env
+ [{:name "DB_USERNAME_FILE"
+ :value
+ "/var/run/secrets/postgres-secret/postgres-user"}
+ {:name "DB_PASSWORD_FILE"
+ :value
+ "/var/run/secrets/postgres-secret/postgres-password"}
+ {:name "FQDN", :value "xx"}]
+ :command ["/app/entrypoint.sh"]
+ :volumeMounts
+ [{:mountPath "/var/nextcloud", :name "cloud-data-volume"}
+ {:name "postgres-secret-volume"
+ :mountPath "/var/run/secrets/postgres-secret"
+ :readOnly true}]}]
+ :volumes
+ [{:name "cloud-data-volume"
+ :persistentVolumeClaim {:claimName "cloud-pvc"}}
+ {:name "postgres-secret-volume"
+ :secret {:secretName "postgres-secret"}}]}
+ (get-in (cut/generate-deployment {:fqdn "xx"}) [:spec :template :spec]))))