diff --git a/envs/production/_apps/nextcloud/app-data.ytt.yaml b/envs/production/_apps/nextcloud/app-data.ytt.yaml new file mode 100644 index 0000000..5a9a3a1 --- /dev/null +++ b/envs/production/_apps/nextcloud/app-data.ytt.yaml @@ -0,0 +1,5 @@ +#@data/values-schema +--- +#@overlay/match-child-defaults missing_ok=True +application: + namespace: nextcloud diff --git a/envs/production/_apps/nextcloud/argocd/ignore-jobs.overlay.ytt.yaml b/envs/production/_apps/nextcloud/argocd/ignore-jobs.overlay.ytt.yaml new file mode 100644 index 0000000..9a505aa --- /dev/null +++ b/envs/production/_apps/nextcloud/argocd/ignore-jobs.overlay.ytt.yaml @@ -0,0 +1,16 @@ +#@ load("@ytt:overlay", "overlay") + +#@overlay/match by=overlay.all, expects="1+" +--- +#@overlay/match-child-defaults missing_ok=True +spec: + ignoreDifferences: + - group: batch + kind: Job + jsonPointers: + - /spec/selector + - /spec/template/metadata/labels + syncPolicy: + syncOptions: + #@overlay/append + - RespectIgnoreDifferences=true diff --git a/envs/production/env-data.ytt.yaml b/envs/production/env-data.ytt.yaml index dbb1451..13e3b49 100644 --- a/envs/production/env-data.ytt.yaml +++ b/envs/production/env-data.ytt.yaml @@ -14,3 +14,4 @@ environment: - proto: hcloud-csi - proto: cloudnative-pg - proto: metrics-server + - proto: nextcloud diff --git a/prototypes/nextcloud/app-data.ytt.yaml b/prototypes/nextcloud/app-data.ytt.yaml new file mode 100644 index 0000000..5a9a3a1 --- /dev/null +++ b/prototypes/nextcloud/app-data.ytt.yaml @@ -0,0 +1,5 @@ +#@data/values-schema +--- +#@overlay/match-child-defaults missing_ok=True +application: + namespace: nextcloud diff --git a/prototypes/nextcloud/helm/nextcloud.yaml b/prototypes/nextcloud/helm/nextcloud.yaml new file mode 100644 index 0000000..541fd75 --- /dev/null +++ b/prototypes/nextcloud/helm/nextcloud.yaml @@ -0,0 +1,198 @@ +--- +_hostname: &hostname nextcloud.tr1ceracop.de + +replicaCount: 1 + +image: + flavor: fpm-alpine + +nginx: + enabled: false + +nextcloud: + host: *hostname + + existingSecret: + enabled: true + secretName: nextcloud-admin-secret + usernameKey: nextcloud-username + passwordKey: nextcloud-password + + objectStore: + s3: + enabled: true + bucket: nextcloud-tr1ceracop + host: nbg1.your-objectstorage.com + port: "443" + ssl: true + region: nbg1 + usePathStyle: true + existingSecret: nextcloud-s3-credentials + secretKeys: + accessKey: ACCESS_KEY_ID + secretKey: SECRET_ACCESS_KEY + + defaultConfigs: + .htaccess: false + apache-pretty-urls.config.php: false + apcu.config.php: false + apps.config.php: false + autoconfig.php: false + redis.config.php: false + reverse-proxy.config.php: false + s3.config.php: false + smtp.config.php: false + swift.config.php: false + upgrade-disable-web.config.php: false + helm-metrics.config.php: false + + extraEnv: + - name: TRUSTED_PROXIES + value: "10.0.0.0/8" + - name: OVERWRITEPROTOCOL + value: "https" + - name: OVERWRITEHOST + value: *hostname + - name: OVERWRITECLIURL + value: "https://nextcloud.tr1ceracop.de" + - name: NC_default_phone_region + value: "DE" + + phpConfigs: + uploadLimit.ini: | + upload_max_filesize = 16G + post_max_size = 16G + max_input_time = 3600 + max_execution_time = 3600 + opcache.ini: | + opcache.enable=1 + opcache.interned_strings_buffer=32 + opcache.max_accelerated_files=10000 + opcache.memory_consumption=256 + opcache.save_comments=1 + opcache.revalidate_freq=60 + + extraSidecarContainers: + - name: caddy + image: caddy:2-alpine + ports: + - name: http + containerPort: 80 + protocol: TCP + volumeMounts: + - name: nextcloud-main + mountPath: /var/www/ + subPath: root + - name: nextcloud-main + mountPath: /var/www/html + subPath: html + - name: nextcloud-main + mountPath: /var/www/html/data + subPath: data + - name: nextcloud-main + mountPath: /var/www/html/config + subPath: config + - name: nextcloud-main + mountPath: /var/www/html/custom_apps + subPath: custom_apps + - name: nextcloud-main + mountPath: /var/www/tmp + subPath: tmp + - name: nextcloud-main + mountPath: /var/www/html/themes + subPath: themes + - name: caddy-config + mountPath: /etc/caddy + resources: + requests: + cpu: 50m + memory: 32Mi + limits: + memory: 64Mi + livenessProbe: + httpGet: + path: /status.php + port: 80 + httpHeaders: + - name: Host + value: *hostname + initialDelaySeconds: 30 + periodSeconds: 15 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /status.php + port: 80 + httpHeaders: + - name: Host + value: *hostname + initialDelaySeconds: 30 + periodSeconds: 15 + timeoutSeconds: 5 + + extraVolumes: + - name: caddy-config + configMap: + name: nextcloud-caddy-config + + strategy: + type: Recreate + +internalDatabase: + enabled: false + +externalDatabase: + enabled: true + type: postgresql + host: nextcloud-cnpg-rw.nextcloud.svc:5432 + database: nextcloud + existingSecret: + enabled: true + secretName: nextcloud-cnpg-app + usernameKey: username + passwordKey: password + +mariadb: + enabled: false + +postgresql: + enabled: false + +redis: + enabled: false + +externalRedis: + enabled: true + host: nextcloud-valkey.nextcloud.svc + port: "6379" + existingSecret: + enabled: true + secretName: nextcloud-valkey-password + passwordKey: password + +cronjob: + enabled: true + +persistence: + enabled: true + size: 2Gi + storageClass: local-path + annotations: + helm.sh/resource-policy: keep + +ingress: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt + tls: + - secretName: nextcloud-tls + hosts: + - *hostname + +resources: + requests: + cpu: 200m + memory: 256Mi + limits: + memory: 512Mi diff --git a/prototypes/nextcloud/vendir/base.ytt.yaml b/prototypes/nextcloud/vendir/base.ytt.yaml new file mode 100644 index 0000000..530cdb0 --- /dev/null +++ b/prototypes/nextcloud/vendir/base.ytt.yaml @@ -0,0 +1,16 @@ +#@ load("@ytt:data", "data") + +#@ app = data.values.application +--- +apiVersion: vendir.k14s.io/v1alpha1 +kind: Config +directories: + - path: #@ "charts/" + app.name + contents: + - path: . + helmChart: + name: #@ app.name + version: #@ app.version + repository: + url: #@ app.url + lazy: true diff --git a/prototypes/nextcloud/vendir/vendir-data.ytt.yaml b/prototypes/nextcloud/vendir/vendir-data.ytt.yaml new file mode 100644 index 0000000..bcee638 --- /dev/null +++ b/prototypes/nextcloud/vendir/vendir-data.ytt.yaml @@ -0,0 +1,8 @@ +#@data/values-schema +--- +#@overlay/match-child-defaults missing_ok=True +application: + #! renovate: datasource=helm + name: nextcloud + url: https://nextcloud.github.io/helm/ + version: 9.0.4 diff --git a/prototypes/nextcloud/ytt/admin-secret-job.ytt.yaml b/prototypes/nextcloud/ytt/admin-secret-job.ytt.yaml new file mode 100644 index 0000000..0c346ed --- /dev/null +++ b/prototypes/nextcloud/ytt/admin-secret-job.ytt.yaml @@ -0,0 +1,85 @@ +#@ load("@ytt:data", "data") + +#@ ns = data.values.application.namespace + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nextcloud-secret-init + namespace: #@ ns + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: nextcloud-secret-init + namespace: #@ ns +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: nextcloud-secret-init + namespace: #@ ns +subjects: + - kind: ServiceAccount + name: nextcloud-secret-init + namespace: #@ ns +roleRef: + kind: Role + name: nextcloud-secret-init + apiGroup: rbac.authorization.k8s.io + +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: nextcloud-secret-init + namespace: #@ ns + annotations: + argocd.argoproj.io/sync-options: Replace=true +spec: + ttlSecondsAfterFinished: 300 + template: + spec: + serviceAccountName: nextcloud-secret-init + restartPolicy: OnFailure + containers: + - name: init + image: alpine/k8s:1.32.3 + command: + - sh + - -c + - | + set -e + + if ! kubectl get secret nextcloud-admin-secret -n ${NAMESPACE} >/dev/null 2>&1; then + PASSWORD=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24) + kubectl create secret generic nextcloud-admin-secret \ + -n ${NAMESPACE} \ + --from-literal=nextcloud-username=admin \ + --from-literal=nextcloud-password="${PASSWORD}" + echo "Created nextcloud-admin-secret" + else + echo "nextcloud-admin-secret already exists, skipping" + fi + + if ! kubectl get secret nextcloud-valkey-password -n ${NAMESPACE} >/dev/null 2>&1; then + VALKEY_PASSWORD=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24) + kubectl create secret generic nextcloud-valkey-password \ + -n ${NAMESPACE} \ + --from-literal=password="${VALKEY_PASSWORD}" + echo "Created nextcloud-valkey-password" + else + echo "nextcloud-valkey-password already exists, skipping" + fi + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace diff --git a/prototypes/nextcloud/ytt/caddy.ytt.yaml b/prototypes/nextcloud/ytt/caddy.ytt.yaml new file mode 100644 index 0000000..0d99f1b --- /dev/null +++ b/prototypes/nextcloud/ytt/caddy.ytt.yaml @@ -0,0 +1,61 @@ +#@ load("@ytt:data", "data") + +#@ ns = data.values.application.namespace + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: nextcloud-caddy-config + namespace: #@ ns +data: + Caddyfile: | + :80 { + root * /var/www/html + + header { + Referrer-Policy "no-referrer" + X-Content-Type-Options "nosniff" + X-Frame-Options "SAMEORIGIN" + X-Permitted-Cross-Domain-Policies "none" + X-Robots-Tag "noindex, nofollow" + X-XSS-Protection "1; mode=block" + -X-Powered-By + } + + redir /.well-known/carddav /remote.php/dav/ 301 + redir /.well-known/caldav /remote.php/dav/ 301 + redir /.well-known/* /index.php{uri} 301 + + @blocked path /build/* /tests/* /config/* /lib/* /3rdparty/* /templates/* /data/* + respond @blocked 404 + + @davclnt { + path / + header User-Agent DavClnt* + } + redir @davclnt /remote.php/webdav/ 302 + + redir /remote /remote.php{uri} 301 + + php_fastcgi 127.0.0.1:9000 { + env HTTPS on + env modHeadersAvailable true + env front_controller_active true + resolve_root_symlink + } + + @static path *.css *.js *.mjs *.svg *.gif *.ico *.jpg *.png *.webp *.wasm *.tflite *.map *.ogg *.flac + header @static Cache-Control "max-age=15778463" + + @fonts path *.otf *.woff *.woff2 + header @fonts Cache-Control "max-age=604800" + + encode gzip + + file_server + + request_body { + max_size 16GB + } + } diff --git a/prototypes/nextcloud/ytt/cnpg-cluster.ytt.yaml b/prototypes/nextcloud/ytt/cnpg-cluster.ytt.yaml new file mode 100644 index 0000000..56c925c --- /dev/null +++ b/prototypes/nextcloud/ytt/cnpg-cluster.ytt.yaml @@ -0,0 +1,36 @@ +#@ load("@ytt:data", "data") + +#@ ns = data.values.application.namespace + +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: nextcloud-cnpg + namespace: #@ ns +spec: + instances: 2 + + bootstrap: + initdb: + database: nextcloud + owner: nextcloud + + storage: + size: 5Gi + storageClass: hcloud-volumes + + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + memory: 512Mi + + postgresql: + parameters: + shared_buffers: "64MB" + effective_cache_size: "128MB" + work_mem: "4MB" + maintenance_work_mem: "32MB" + max_connections: "100" diff --git a/prototypes/nextcloud/ytt/ns.ytt.yaml b/prototypes/nextcloud/ytt/ns.ytt.yaml new file mode 100644 index 0000000..f66069b --- /dev/null +++ b/prototypes/nextcloud/ytt/ns.ytt.yaml @@ -0,0 +1,18 @@ +#@ load("@ytt:data", "data") +#@ load("@ytt:overlay", "overlay") + +#@ ns = data.values.application.namespace + +--- +apiVersion: v1 +kind: Namespace +metadata: + name: #@ ns + labels: + pod-security.kubernetes.io/enforce: privileged + +#@overlay/match by=overlay.all, expects="1+" +--- +metadata: + #@overlay/match missing_ok=True + namespace: #@ ns diff --git a/prototypes/nextcloud/ytt/valkey.ytt.yaml b/prototypes/nextcloud/ytt/valkey.ytt.yaml new file mode 100644 index 0000000..ec29459 --- /dev/null +++ b/prototypes/nextcloud/ytt/valkey.ytt.yaml @@ -0,0 +1,78 @@ +#@ load("@ytt:data", "data") + +#@ ns = data.values.application.namespace + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nextcloud-valkey + namespace: #@ ns + labels: + app.kubernetes.io/name: valkey + app.kubernetes.io/instance: nextcloud +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: valkey + app.kubernetes.io/instance: nextcloud + template: + metadata: + labels: + app.kubernetes.io/name: valkey + app.kubernetes.io/instance: nextcloud + spec: + containers: + - name: valkey + image: valkey/valkey:8-alpine + args: + - valkey-server + - --requirepass + - $(VALKEY_PASSWORD) + env: + - name: VALKEY_PASSWORD + valueFrom: + secretKeyRef: + name: nextcloud-valkey-password + key: password + ports: + - name: valkey + containerPort: 6379 + protocol: TCP + resources: + requests: + cpu: 50m + memory: 64Mi + limits: + memory: 128Mi + livenessProbe: + tcpSocket: + port: valkey + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + tcpSocket: + port: valkey + initialDelaySeconds: 5 + periodSeconds: 5 + +--- +apiVersion: v1 +kind: Service +metadata: + name: nextcloud-valkey + namespace: #@ ns + labels: + app.kubernetes.io/name: valkey + app.kubernetes.io/instance: nextcloud +spec: + type: ClusterIP + ports: + - port: 6379 + targetPort: valkey + protocol: TCP + name: valkey + selector: + app.kubernetes.io/name: valkey + app.kubernetes.io/instance: nextcloud diff --git a/rendered/argocd/production/app-nextcloud.yaml b/rendered/argocd/production/app-nextcloud.yaml new file mode 100644 index 0000000..d8ed32b --- /dev/null +++ b/rendered/argocd/production/app-nextcloud.yaml @@ -0,0 +1,32 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + myks.dev/environment: production + finalizers: + - resources-finalizer.argocd.argoproj.io + name: app-production-nextcloud + namespace: argocd +spec: + destination: + namespace: nextcloud + server: https://kubernetes.default.svc + ignoreDifferences: + - group: batch + jsonPointers: + - /spec/selector + - /spec/template/metadata/labels + kind: Job + project: env-production + source: + path: rendered/envs/production/nextcloud + repoURL: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + targetRevision: main + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true + - RespectIgnoreDifferences=true diff --git a/rendered/envs/production/nextcloud/cluster-nextcloud-cnpg.yaml b/rendered/envs/production/nextcloud/cluster-nextcloud-cnpg.yaml new file mode 100644 index 0000000..922eca0 --- /dev/null +++ b/rendered/envs/production/nextcloud/cluster-nextcloud-cnpg.yaml @@ -0,0 +1,29 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + name: nextcloud-cnpg + namespace: nextcloud +spec: + bootstrap: + initdb: + database: nextcloud + owner: nextcloud + instances: 2 + postgresql: + parameters: + effective_cache_size: 128MB + maintenance_work_mem: 32MB + max_connections: "100" + shared_buffers: 64MB + work_mem: 4MB + resources: + limits: + memory: 512Mi + requests: + cpu: 100m + memory: 256Mi + storage: + size: 5Gi + storageClass: hcloud-volumes diff --git a/rendered/envs/production/nextcloud/configmap-nextcloud-caddy-config.yaml b/rendered/envs/production/nextcloud/configmap-nextcloud-caddy-config.yaml new file mode 100644 index 0000000..2a0f413 --- /dev/null +++ b/rendered/envs/production/nextcloud/configmap-nextcloud-caddy-config.yaml @@ -0,0 +1,58 @@ +apiVersion: v1 +data: + Caddyfile: | + :80 { + root * /var/www/html + + header { + Referrer-Policy "no-referrer" + X-Content-Type-Options "nosniff" + X-Frame-Options "SAMEORIGIN" + X-Permitted-Cross-Domain-Policies "none" + X-Robots-Tag "noindex, nofollow" + X-XSS-Protection "1; mode=block" + -X-Powered-By + } + + redir /.well-known/carddav /remote.php/dav/ 301 + redir /.well-known/caldav /remote.php/dav/ 301 + redir /.well-known/* /index.php{uri} 301 + + @blocked path /build/* /tests/* /config/* /lib/* /3rdparty/* /templates/* /data/* + respond @blocked 404 + + @davclnt { + path / + header User-Agent DavClnt* + } + redir @davclnt /remote.php/webdav/ 302 + + redir /remote /remote.php{uri} 301 + + php_fastcgi 127.0.0.1:9000 { + env HTTPS on + env modHeadersAvailable true + env front_controller_active true + resolve_root_symlink + } + + @static path *.css *.js *.mjs *.svg *.gif *.ico *.jpg *.png *.webp *.wasm *.tflite *.map *.ogg *.flac + header @static Cache-Control "max-age=15778463" + + @fonts path *.otf *.woff *.woff2 + header @fonts Cache-Control "max-age=604800" + + encode gzip + + file_server + + request_body { + max_size 16GB + } + } +kind: ConfigMap +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + name: nextcloud-caddy-config + namespace: nextcloud diff --git a/rendered/envs/production/nextcloud/configmap-nextcloud-phpconfig.yaml b/rendered/envs/production/nextcloud/configmap-nextcloud-phpconfig.yaml new file mode 100644 index 0000000..927eb4d --- /dev/null +++ b/rendered/envs/production/nextcloud/configmap-nextcloud-phpconfig.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +data: + opcache.ini: |- + opcache.enable=1 + opcache.interned_strings_buffer=32 + opcache.max_accelerated_files=10000 + opcache.memory_consumption=256 + opcache.save_comments=1 + opcache.revalidate_freq=60 + uploadLimit.ini: |- + upload_max_filesize = 16G + post_max_size = 16G + max_input_time = 3600 + max_execution_time = 3600 +kind: ConfigMap +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + labels: + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nextcloud + app.kubernetes.io/version: 33.0.0 + helm.sh/chart: nextcloud-9.0.4 + name: nextcloud-phpconfig + namespace: nextcloud diff --git a/rendered/envs/production/nextcloud/deployment-nextcloud-valkey.yaml b/rendered/envs/production/nextcloud/deployment-nextcloud-valkey.yaml new file mode 100644 index 0000000..c311a8f --- /dev/null +++ b/rendered/envs/production/nextcloud/deployment-nextcloud-valkey.yaml @@ -0,0 +1,55 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + labels: + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: valkey + name: nextcloud-valkey + namespace: nextcloud +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: valkey + template: + metadata: + labels: + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: valkey + spec: + containers: + - args: + - valkey-server + - --requirepass + - $(VALKEY_PASSWORD) + env: + - name: VALKEY_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud-valkey-password + image: valkey/valkey:8-alpine + livenessProbe: + initialDelaySeconds: 10 + periodSeconds: 10 + tcpSocket: + port: valkey + name: valkey + ports: + - containerPort: 6379 + name: valkey + protocol: TCP + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 5 + tcpSocket: + port: valkey + resources: + limits: + memory: 128Mi + requests: + cpu: 50m + memory: 64Mi diff --git a/rendered/envs/production/nextcloud/deployment-nextcloud.yaml b/rendered/envs/production/nextcloud/deployment-nextcloud.yaml new file mode 100644 index 0000000..4009e7c --- /dev/null +++ b/rendered/envs/production/nextcloud/deployment-nextcloud.yaml @@ -0,0 +1,358 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nextcloud + app.kubernetes.io/version: 33.0.0 + helm.sh/chart: nextcloud-9.0.4 + name: nextcloud + namespace: nextcloud +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: nextcloud + strategy: + type: Recreate + template: + metadata: + annotations: + hooks-hash: 9525c2748a6c7cd0e28ec740623d0b3fa5a75c83b51ccfd136bc89c76737b204 + nextcloud-config-hash: 97fd373864ae7c5da0eb066761ee479483364e3957160cacca360fc6a66c03f7 + php-config-hash: b638f66fd8d65de8364dbad6efc59a6524c7b2e2377b5623cf5e921e4d3d2400 + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: nextcloud + spec: + containers: + - env: + - name: POSTGRES_HOST + value: nextcloud-cnpg-rw.nextcloud.svc:5432 + - name: POSTGRES_DB + value: nextcloud + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + key: username + name: nextcloud-cnpg-app + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud-cnpg-app + - name: NEXTCLOUD_ADMIN_USER + valueFrom: + secretKeyRef: + key: nextcloud-username + name: nextcloud-admin-secret + - name: NEXTCLOUD_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: nextcloud-password + name: nextcloud-admin-secret + - name: NEXTCLOUD_TRUSTED_DOMAINS + value: nextcloud.tr1ceracop.de + - name: OPENMETRICS_ALLOWED_CLIENTS + value: 127.0.0.1,10.42.0.0/16,10.43.0.0/16 + - name: NEXTCLOUD_DATA_DIR + value: /var/www/html/data + - name: REDIS_HOST + value: nextcloud-valkey.nextcloud.svc + - name: REDIS_HOST_PORT + value: "6379" + - name: REDIS_HOST_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud-valkey-password + - name: OBJECTSTORE_S3_SSL + value: "true" + - name: OBJECTSTORE_S3_USEPATH_STYLE + value: "true" + - name: OBJECTSTORE_S3_AUTOCREATE + value: "false" + - name: OBJECTSTORE_S3_REGION + value: nbg1 + - name: OBJECTSTORE_S3_PORT + value: "443" + - name: OBJECTSTORE_S3_STORAGE_CLASS + value: STANDARD + - name: OBJECTSTORE_S3_HOST + value: nbg1.your-objectstorage.com + - name: OBJECTSTORE_S3_BUCKET + value: nextcloud-tr1ceracop + - name: OBJECTSTORE_S3_KEY + valueFrom: + secretKeyRef: + key: ACCESS_KEY_ID + name: nextcloud-s3-credentials + - name: OBJECTSTORE_S3_SECRET + valueFrom: + secretKeyRef: + key: SECRET_ACCESS_KEY + name: nextcloud-s3-credentials + - name: OBJECTSTORE_S3_SSE_C_KEY + value: "" + - name: TRUSTED_PROXIES + value: 10.0.0.0/8 + - name: OVERWRITEPROTOCOL + value: https + - name: OVERWRITEHOST + value: nextcloud.tr1ceracop.de + - name: OVERWRITECLIURL + value: https://nextcloud.tr1ceracop.de + - name: NC_default_phone_region + value: DE + image: docker.io/library/nextcloud:33.0.0-fpm-alpine + imagePullPolicy: IfNotPresent + livenessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: + - name: Host + value: nextcloud.tr1ceracop.de + path: /status.php + port: 80 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + name: nextcloud + ports: + - containerPort: 80 + name: http + protocol: TCP + readinessProbe: + failureThreshold: 3 + httpGet: + httpHeaders: + - name: Host + value: nextcloud.tr1ceracop.de + path: /status.php + port: 80 + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + resources: + limits: + memory: 512Mi + requests: + cpu: 200m + memory: 256Mi + volumeMounts: + - mountPath: /var/www/ + name: nextcloud-main + subPath: root + - mountPath: /var/www/html + name: nextcloud-main + subPath: html + - mountPath: /var/www/html/data + name: nextcloud-main + subPath: data + - mountPath: /var/www/html/config + name: nextcloud-main + subPath: config + - mountPath: /var/www/html/custom_apps + name: nextcloud-main + subPath: custom_apps + - mountPath: /var/www/tmp + name: nextcloud-main + subPath: tmp + - mountPath: /var/www/html/themes + name: nextcloud-main + subPath: themes + - mountPath: /usr/local/etc/php/conf.d/opcache.ini + name: nextcloud-phpconfig + subPath: opcache.ini + - mountPath: /usr/local/etc/php/conf.d/uploadLimit.ini + name: nextcloud-phpconfig + subPath: uploadLimit.ini + - command: + - /cron.sh + env: + - name: POSTGRES_HOST + value: nextcloud-cnpg-rw.nextcloud.svc:5432 + - name: POSTGRES_DB + value: nextcloud + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + key: username + name: nextcloud-cnpg-app + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud-cnpg-app + - name: NEXTCLOUD_ADMIN_USER + valueFrom: + secretKeyRef: + key: nextcloud-username + name: nextcloud-admin-secret + - name: NEXTCLOUD_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + key: nextcloud-password + name: nextcloud-admin-secret + - name: NEXTCLOUD_TRUSTED_DOMAINS + value: nextcloud.tr1ceracop.de + - name: OPENMETRICS_ALLOWED_CLIENTS + value: 127.0.0.1,10.42.0.0/16,10.43.0.0/16 + - name: NEXTCLOUD_DATA_DIR + value: /var/www/html/data + - name: REDIS_HOST + value: nextcloud-valkey.nextcloud.svc + - name: REDIS_HOST_PORT + value: "6379" + - name: REDIS_HOST_PASSWORD + valueFrom: + secretKeyRef: + key: password + name: nextcloud-valkey-password + - name: OBJECTSTORE_S3_SSL + value: "true" + - name: OBJECTSTORE_S3_USEPATH_STYLE + value: "true" + - name: OBJECTSTORE_S3_AUTOCREATE + value: "false" + - name: OBJECTSTORE_S3_REGION + value: nbg1 + - name: OBJECTSTORE_S3_PORT + value: "443" + - name: OBJECTSTORE_S3_STORAGE_CLASS + value: STANDARD + - name: OBJECTSTORE_S3_HOST + value: nbg1.your-objectstorage.com + - name: OBJECTSTORE_S3_BUCKET + value: nextcloud-tr1ceracop + - name: OBJECTSTORE_S3_KEY + valueFrom: + secretKeyRef: + key: ACCESS_KEY_ID + name: nextcloud-s3-credentials + - name: OBJECTSTORE_S3_SECRET + valueFrom: + secretKeyRef: + key: SECRET_ACCESS_KEY + name: nextcloud-s3-credentials + - name: OBJECTSTORE_S3_SSE_C_KEY + value: "" + - name: TRUSTED_PROXIES + value: 10.0.0.0/8 + - name: OVERWRITEPROTOCOL + value: https + - name: OVERWRITEHOST + value: nextcloud.tr1ceracop.de + - name: OVERWRITECLIURL + value: https://nextcloud.tr1ceracop.de + - name: NC_default_phone_region + value: DE + image: docker.io/library/nextcloud:33.0.0-fpm-alpine + imagePullPolicy: IfNotPresent + name: nextcloud-cron + resources: {} + volumeMounts: + - mountPath: /var/www/ + name: nextcloud-main + subPath: root + - mountPath: /var/www/html + name: nextcloud-main + subPath: html + - mountPath: /var/www/html/data + name: nextcloud-main + subPath: data + - mountPath: /var/www/html/config + name: nextcloud-main + subPath: config + - mountPath: /var/www/html/custom_apps + name: nextcloud-main + subPath: custom_apps + - mountPath: /var/www/tmp + name: nextcloud-main + subPath: tmp + - mountPath: /var/www/html/themes + name: nextcloud-main + subPath: themes + - mountPath: /usr/local/etc/php/conf.d/opcache.ini + name: nextcloud-phpconfig + subPath: opcache.ini + - mountPath: /usr/local/etc/php/conf.d/uploadLimit.ini + name: nextcloud-phpconfig + subPath: uploadLimit.ini + - image: caddy:2-alpine + livenessProbe: + httpGet: + httpHeaders: + - name: Host + value: nextcloud.tr1ceracop.de + path: /status.php + port: 80 + initialDelaySeconds: 30 + periodSeconds: 15 + timeoutSeconds: 5 + name: caddy + ports: + - containerPort: 80 + name: http + protocol: TCP + readinessProbe: + httpGet: + httpHeaders: + - name: Host + value: nextcloud.tr1ceracop.de + path: /status.php + port: 80 + initialDelaySeconds: 30 + periodSeconds: 15 + timeoutSeconds: 5 + resources: + limits: + memory: 64Mi + requests: + cpu: 50m + memory: 32Mi + volumeMounts: + - mountPath: /var/www/ + name: nextcloud-main + subPath: root + - mountPath: /var/www/html + name: nextcloud-main + subPath: html + - mountPath: /var/www/html/data + name: nextcloud-main + subPath: data + - mountPath: /var/www/html/config + name: nextcloud-main + subPath: config + - mountPath: /var/www/html/custom_apps + name: nextcloud-main + subPath: custom_apps + - mountPath: /var/www/tmp + name: nextcloud-main + subPath: tmp + - mountPath: /var/www/html/themes + name: nextcloud-main + subPath: themes + - mountPath: /etc/caddy + name: caddy-config + securityContext: + fsGroup: 33 + volumes: + - name: nextcloud-main + persistentVolumeClaim: + claimName: nextcloud-nextcloud + - configMap: + name: nextcloud-phpconfig + name: nextcloud-phpconfig + - configMap: + name: nextcloud-caddy-config + name: caddy-config diff --git a/rendered/envs/production/nextcloud/ingress-nextcloud.yaml b/rendered/envs/production/nextcloud/ingress-nextcloud.yaml new file mode 100644 index 0000000..39dc9b7 --- /dev/null +++ b/rendered/envs/production/nextcloud/ingress-nextcloud.yaml @@ -0,0 +1,32 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + cert-manager.io/cluster-issuer: letsencrypt + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nextcloud + app.kubernetes.io/version: 33.0.0 + helm.sh/chart: nextcloud-9.0.4 + name: nextcloud + namespace: nextcloud +spec: + ingressClassName: traefik + rules: + - host: nextcloud.tr1ceracop.de + http: + paths: + - backend: + service: + name: nextcloud + port: + number: 8080 + path: / + pathType: Prefix + tls: + - hosts: + - nextcloud.tr1ceracop.de + secretName: nextcloud-tls diff --git a/rendered/envs/production/nextcloud/job-nextcloud-secret-init.yaml b/rendered/envs/production/nextcloud/job-nextcloud-secret-init.yaml new file mode 100644 index 0000000..f051129 --- /dev/null +++ b/rendered/envs/production/nextcloud/job-nextcloud-secret-init.yaml @@ -0,0 +1,48 @@ +apiVersion: batch/v1 +kind: Job +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + argocd.argoproj.io/sync-options: Replace=true + name: nextcloud-secret-init + namespace: nextcloud +spec: + template: + spec: + containers: + - command: + - sh + - -c + - | + set -e + + if ! kubectl get secret nextcloud-admin-secret -n ${NAMESPACE} >/dev/null 2>&1; then + PASSWORD=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24) + kubectl create secret generic nextcloud-admin-secret \ + -n ${NAMESPACE} \ + --from-literal=nextcloud-username=admin \ + --from-literal=nextcloud-password="${PASSWORD}" + echo "Created nextcloud-admin-secret" + else + echo "nextcloud-admin-secret already exists, skipping" + fi + + if ! kubectl get secret nextcloud-valkey-password -n ${NAMESPACE} >/dev/null 2>&1; then + VALKEY_PASSWORD=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24) + kubectl create secret generic nextcloud-valkey-password \ + -n ${NAMESPACE} \ + --from-literal=password="${VALKEY_PASSWORD}" + echo "Created nextcloud-valkey-password" + else + echo "nextcloud-valkey-password already exists, skipping" + fi + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: alpine/k8s:1.32.3 + name: init + restartPolicy: OnFailure + serviceAccountName: nextcloud-secret-init + ttlSecondsAfterFinished: 300 diff --git a/rendered/envs/production/nextcloud/namespace-nextcloud.yaml b/rendered/envs/production/nextcloud/namespace-nextcloud.yaml new file mode 100644 index 0000000..e182df4 --- /dev/null +++ b/rendered/envs/production/nextcloud/namespace-nextcloud.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Namespace +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + labels: + pod-security.kubernetes.io/enforce: privileged + name: nextcloud + namespace: nextcloud diff --git a/rendered/envs/production/nextcloud/persistentvolumeclaim-nextcloud-nextcloud.yaml b/rendered/envs/production/nextcloud/persistentvolumeclaim-nextcloud-nextcloud.yaml new file mode 100644 index 0000000..f8edf43 --- /dev/null +++ b/rendered/envs/production/nextcloud/persistentvolumeclaim-nextcloud-nextcloud.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: nextcloud + app.kubernetes.io/version: 33.0.0 + helm.sh/chart: nextcloud-9.0.4 + name: nextcloud-nextcloud + namespace: nextcloud +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + storageClassName: local-path diff --git a/rendered/envs/production/nextcloud/role-nextcloud-secret-init.yaml b/rendered/envs/production/nextcloud/role-nextcloud-secret-init.yaml new file mode 100644 index 0000000..32421f5 --- /dev/null +++ b/rendered/envs/production/nextcloud/role-nextcloud-secret-init.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + name: nextcloud-secret-init + namespace: nextcloud +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create diff --git a/rendered/envs/production/nextcloud/rolebinding-nextcloud-secret-init.yaml b/rendered/envs/production/nextcloud/rolebinding-nextcloud-secret-init.yaml new file mode 100644 index 0000000..114f318 --- /dev/null +++ b/rendered/envs/production/nextcloud/rolebinding-nextcloud-secret-init.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + name: nextcloud-secret-init + namespace: nextcloud +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: nextcloud-secret-init +subjects: + - kind: ServiceAccount + name: nextcloud-secret-init + namespace: nextcloud diff --git a/rendered/envs/production/nextcloud/service-nextcloud-valkey.yaml b/rendered/envs/production/nextcloud/service-nextcloud-valkey.yaml new file mode 100644 index 0000000..3e0a7d3 --- /dev/null +++ b/rendered/envs/production/nextcloud/service-nextcloud-valkey.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + labels: + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: valkey + name: nextcloud-valkey + namespace: nextcloud +spec: + ports: + - name: valkey + port: 6379 + protocol: TCP + targetPort: valkey + selector: + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: valkey + type: ClusterIP diff --git a/rendered/envs/production/nextcloud/service-nextcloud.yaml b/rendered/envs/production/nextcloud/service-nextcloud.yaml new file mode 100644 index 0000000..9038ce7 --- /dev/null +++ b/rendered/envs/production/nextcloud/service-nextcloud.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + labels: + app.kubernetes.io/component: app + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/monitor: enabled + app.kubernetes.io/name: nextcloud + app.kubernetes.io/version: 33.0.0 + helm.sh/chart: nextcloud-9.0.4 + name: nextcloud + namespace: nextcloud +spec: + ports: + - name: http + port: 8080 + protocol: TCP + targetPort: 80 + selector: + app.kubernetes.io/component: app + app.kubernetes.io/instance: nextcloud + app.kubernetes.io/name: nextcloud + type: ClusterIP diff --git a/rendered/envs/production/nextcloud/serviceaccount-nextcloud-secret-init.yaml b/rendered/envs/production/nextcloud/serviceaccount-nextcloud-secret-init.yaml new file mode 100644 index 0000000..f713d4a --- /dev/null +++ b/rendered/envs/production/nextcloud/serviceaccount-nextcloud-secret-init.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + annotations: + a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git + name: nextcloud-secret-init + namespace: nextcloud