feat: add nextcloud#1609
Conversation
📝 WalkthroughWalkthroughNextcloud の Kubernetes デプロイメント環境を新規構築。Kustomize で Valkey Helm チャート、複数マニフェストリソースを統合管理し、SOPS 暗号化シークレット、cert-manager TLS、Traefik イングレス、Nextcloud Deployment(nginx プロキシ、PHP、cron)、MySQL 接続、キャッシュ層を設定。 ChangesNextcloud Kubernetes デプロイメントスタック
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Traefik
participant nginx
participant PHP as PHP-FPM<br/>(Nextcloud)
participant Valkey
participant MySQL
User->>Traefik: HTTPS GET /index.php<br/>drive.trap.jp
Traefik->>Traefik: TLS negotiate<br/>(nextcloud-tls cert)
Traefik->>nginx: HTTP request<br/>port 80
nginx->>nginx: match location ~ \.php
nginx->>nginx: rewrite to<br/>Nextcloud frontcontroller
nginx->>PHP: FastCGI pass<br/>SCRIPT_FILENAME, PATH_INFO,<br/>HTTPS=on
PHP->>Valkey: GET session cache<br/>(nextcloud)
Valkey-->>PHP: session data
PHP->>MySQL: SELECT config,<br/>user data
MySQL-->>PHP: query result
PHP->>PHP: render page
PHP-->>nginx: PHP response
nginx->>nginx: apply security headers<br/>Cache-Control, X-Frame-Options
nginx-->>Traefik: HTTP response
Traefik-->>User: HTTPS response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Diff@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: valkey
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/name: valkey
+ app.kubernetes.io/version: "9.0.2"
+ helm.sh/chart: valkey-0.9.4
+ automountServiceAccountToken: false
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: nextcloud-config
+ namespace: nextcloud
+ data:
+ base.config.php: |
+ <?php
+ $CONFIG = array (
+ 'passwordsalt' => getenv('NEXTCLOUD_PASSWORDSALT'),
+ 'secret' => getenv('NEXTCLOUD_SECRET'),
+ 'instanceid' => getenv('NEXTCLOUD_INSTANCEID'),
+ 'overwrite.cli.url' => 'https://drive.trap.jp',
+ 'upgrade.disable-web' => true,
+ 'trusted_domains' => ['drive.trap.jp'],
+ 'apps_paths' => array (
+ 0 => array (
+ 'path' => '/var/www/html/apps',
+ 'url' => '/apps',
+ 'writable' => false,
+ ),
+ 1 => array (
+ 'path' => '/var/www/html/custom_apps',
+ 'url' => '/custom_apps',
+ 'writable' => true,
+ ),
+ ),
+
+ 'mail_smtpmode' => 'smtp',
+ 'mail_smtphost' => 'smtp.sendgrid.host',
+ 'mail_smtpport' => '465',
+ 'mail_smtpsecure' => 'ssl',
+ 'mail_smtpauth' => true,
+ 'mail_smtpauthtype' => 'LOGIN',
+ 'mail_smtpname' => 'apikey',
+ 'mail_smtppassword' => getenv('SMTP_PASSWORD'),
+ 'mail_from_address' => 'drive.system',
+ 'mail_domain' => 'trap.jp',
+
+ 'memcache.local' => '\OC\Memcache\APCu',
+ 'memcache.distributed' => '\OC\Memcache\Redis',
+ 'memcache.locking' => '\OC\Memcache\Redis',
+ 'redis' => array(
+ 'host' => 'valkey',
+ 'user' => 'default',
+ 'password' => getenv('VALKEY_PASSWORD'),
+ ),
+
+ 'objectstore' => array(
+ 'class' => '\OC\Files\ObjectStore\S3',
+ 'arguments' => array(
+ 'bucket' => 'trap-nextcloud',
+ 'region' => 'ap-northeast-1',
+ 'hostname' => 's3.ap-northeast-1.wasabisys.com',
+ 'use_ssl' => true,
+ 'key' => getenv('S3_ACCESS_KEY'),
+ 'secret' => getenv('S3_SECRET_KEY'),
+ 'objectPrefix' => 'urn:oid:',
+ 'autocreate' => false,
+ 'use_path_style' => true,
+ ),
+ ),
+
+ 'dbtype' => 'mysql',
+ 'dbhost' => 'tailscale.kmbk.tokyotech.org',
+ 'dbuser' => 'service_drive',
+ 'dbpassword' => getenv('DB_PASSWORD'),
+ 'dbname' => 'service_drive',
+ 'dbtableprefix' => 'oc_',
+ 'mysql.utf8mb4' => true,
+ );
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: nextcloud-nginxconfig
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/name: nextcloud
+ data:
+ default.conf: |
+ # Based on https://github.com/nextcloud/helm/blob/d4f84d9be0d1774d8c9119ba87f2a9ca4379b2d3/charts/nextcloud/files/nginx.config.tpl
+
+ upstream php-handler {
+ server 127.0.0.1:9000;
+ }
+
+ map $http_x_forwarded_proto $real_scheme {
+ default $scheme;
+ https https;
+ }
+
+ map $http_x_forwarded_port $real_port {
+ default $server_port;
+ 443 443;
+ }
+
+ # Set the `immutable` cache control options only for assets with a cache busting `v` argument
+ map $arg_v $asset_immutable {
+ "" "";
+ default ", immutable";
+ }
+
+ server {
+ listen 80;
+
+ # Path to the root of your installation
+ root /var/www/html;
+
+ # Prevent nginx HTTP Server Detection
+ server_tokens off;
+
+ add_header Referrer-Policy "no-referrer" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "noindex, nofollow" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+
+ client_max_body_size 10G;
+ client_body_timeout 300s;
+ fastcgi_buffers 64 4K;
+ fastcgi_read_timeout 3600s;
+
+ # Enable gzip but do not remove ETag headers
+ gzip on;
+ gzip_vary on;
+ gzip_comp_level 4;
+ gzip_min_length 256;
+ gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
+ gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
+
+ # Pagespeed is not supported by Nextcloud, so if your server is built
+ # with the `ngx_pagespeed` module, uncomment this line to disable it.
+ #pagespeed off;
+
+ # The settings allows you to optimize the HTTP2 bandwidth.
+ # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
+ # for tuning hints
+ client_body_buffer_size 512k;
+
+ # Remove X-Powered-By, which is an information leak
+ fastcgi_hide_header X-Powered-By;
+
+ # Set .mjs and .wasm MIME types
+ # Either include it in the default mime.types list
+ # and include that list explicitly or add the file extension
+ # only for Nextcloud like below:
+ include mime.types;
+ types {
+ text/javascript js mjs;
+ application/wasm wasm;
+ }
+
+ # Specify how to handle directories -- specifying `/index.php$request_uri`
+ # here as the fallback means that Nginx always exhibits the desired behaviour
+ # when a client requests a path that corresponds to a directory that exists
+ # on the server. In particular, if that directory contains an index.php file,
+ # that file is correctly served; if it doesn't, then the request is passed to
+ # the front-end controller. This consistent behaviour means that we don't need
+ # to specify custom rules for certain paths (e.g. images and other assets,
+ # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
+ # `try_files $uri $uri/ /index.php$request_uri`
+ # always provides the desired behaviour.
+ index index.php index.html /index.php$request_uri;
+
+ # Rule borrowed from `.htaccess` to handle Microsoft DAV clients
+ location = / {
+ if ( $http_user_agent ~ ^DavClnt ) {
+ return 302 $real_scheme://$host:$real_port/remote.php/webdav/$is_args$args;
+ }
+ }
+
+ location = /robots.txt {
+ allow all;
+ log_not_found off;
+ access_log off;
+ }
+
+ # Make a regex exception for `/.well-known` so that clients can still
+ # access it despite the existence of the regex rule
+ # `location ~ /(\.|autotest|...)` which would otherwise handle requests
+ # for `/.well-known`.
+ location ^~ /.well-known {
+ # The following 6 rules are borrowed from `.htaccess`
+
+ location = /.well-known/carddav { return 301 $real_scheme://$host:$real_port/remote.php/dav/; }
+ location = /.well-known/caldav { return 301 $real_scheme://$host:$real_port/remote.php/dav/; }
+
+ # Let Nextcloud's API for `/.well-known` URIs handle all other
+ # requests by passing them to the front-end controller.
+ return 301 $real_scheme://$host:$real_port/index.php$request_uri;
+ }
+
+ # Rules borrowed from `.htaccess` to hide certain paths from clients
+ location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
+ location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
+
+ # Ensure this block, which passes PHP files to the PHP process, is above the blocks
+ # which handle static assets (as seen below). If this block is not declared first,
+ # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
+ # to the URI, resulting in a HTTP 500 error response.
+ location ~ \.php(?:$|/) {
+ # Required for legacy support
+ rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri;
+
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ set $path_info $fastcgi_path_info;
+
+ try_files $fastcgi_script_name =404;
+
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param PATH_INFO $path_info;
+ fastcgi_param HTTPS on;
+
+ fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
+ fastcgi_param front_controller_active true; # Enable pretty urls
+ fastcgi_pass php-handler;
+
+ fastcgi_intercept_errors on;
+ fastcgi_request_buffering off;
+
+ fastcgi_max_temp_file_size 0;
+ }
+
+ location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$ {
+ try_files $uri /index.php$request_uri;
+ expires 6M; # Cache-Control policy borrowed from `.htaccess`
+ access_log off; # Optional: Don't log access to assets
+ }
+
+ location ~ \.(otf|woff2?)$ {
+ try_files $uri /index.php$request_uri;
+ expires 7d; # Cache-Control policy borrowed from `.htaccess`
+ access_log off; # Optional: Don't log access to assets
+ }
+
+ # Rule borrowed from `.htaccess`
+ location /remote {
+ return 301 $real_scheme://$host:$real_port/remote.php$request_uri;
+ }
+
+ location / {
+ try_files $uri $uri/ /index.php$request_uri;
+ }
+ }
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: valkey-init-scripts
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/name: valkey
+ app.kubernetes.io/version: "9.0.2"
+ helm.sh/chart: valkey-0.9.4
+ data:
+ init.sh: |
+ #!/bin/sh
+ set -eu
+
+ # Default config paths
+ VALKEY_CONFIG=${VALKEY_CONFIG_PATH:-/data/conf/valkey.conf}
+
+ LOGFILE="/data/init.log"
+ DATA_DIR="/data/conf"
+
+ # Logging function (outputs to stderr and file)
+ log() {
+ echo "$(date) $1" | tee -a "$LOGFILE" >&2
+ }
+ # Function to get password for a user
+ # Usage: get_user_password <username> [password_key]
+ # Returns: password via stdout, exits with error if not found
+ get_user_password() {
+ username="$1"
+ password_key="${2:-$username}"
+ password=""
+ # Try to get password from existing secret first (priority)
+ if [ -f "/valkey-users-secret/$password_key" ]; then
+ password=$(cat "/valkey-users-secret/$password_key")
+ log "Using password from existing secret for user $username"
+ elif [ -f "/valkey-auth-secret/${username}-password" ]; then
+ # Fallback to inline password
+ password=$(cat "/valkey-auth-secret/${username}-password")
+ log "Using inline password for user $username"
+ else
+ log "ERROR: No password found for user $username"
+ return 1
+ fi
+
+ echo "$password"
+ }
+
+ # Clean old log if requested
+ if [ "${KEEP_OLD_LOGS:-false}" != "true" ]; then
+ rm -f "$LOGFILE"
+ fi
+
+ if [ -f "$LOGFILE" ]; then
+ log "Detected restart of this instance ($HOSTNAME)"
+ fi
+
+ log "Creating configuration in $DATA_DIR..."
+ mkdir -p "$DATA_DIR"
+ rm -f "$VALKEY_CONFIG"
+
+
+ # Base valkey.conf
+ log "Generating base valkey.conf"
+ {
+ echo "port 6379"
+ echo "protected-mode no"
+ echo "bind * -::*"
+ echo "dir /data"
+ } >>"$VALKEY_CONFIG"
+ # Create secure directory for ACL file
+ log "Creating /etc/valkey directory for ACL file"
+ mkdir -p /etc/valkey
+
+ # Set aclfile path in valkey.conf
+ echo "aclfile /etc/valkey/users.acl" >>"$VALKEY_CONFIG"
+
+ # Remove or reset existing ACL file if present (it may be read-only from previous run)
+ log "Preparing ACL file at /etc/valkey/users.acl"
+ if [ -f /etc/valkey/users.acl ]; then
+ log "Removing existing read-only users.acl file"
+ chmod 0600 /etc/valkey/users.acl
+ rm -f /etc/valkey/users.acl
+ fi
+
+ # Create ACL file with secure permissions
+ touch /etc/valkey/users.acl
+ chmod 0600 /etc/valkey/users.acl
+ # Generate ACL entries for each user
+ log "Generating ACL entries for users"
+
+ # User: default
+ PASSWORD=$(get_user_password "default" "default") || exit 1
+
+ # Hash the password and write ACL entry
+ PASSHASH=$(echo -n "$PASSWORD" | sha256sum | cut -f 1 -d " ")
+ echo "user default on #$PASSHASH ~* &* +@all" >> /etc/valkey/users.acl
+
+ # Set final permissions
+ chmod 0400 /etc/valkey/users.acl
+ log "ACL file created with 0400 permissions"
+
+ # Append extra configs if present
+ if [ -f /usr/local/etc/valkey/valkey.conf ]; then
+ log "Appending /usr/local/etc/valkey/valkey.conf"
+ cat /usr/local/etc/valkey/valkey.conf >>"$VALKEY_CONFIG"
+ fi
+ if [ -d /extravalkeyconfigs ]; then
+ log "Appending files in /extravalkeyconfigs/"
+ cat /extravalkeyconfigs/* >>"$VALKEY_CONFIG"
+ fi
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: secret-env
+ namespace: nextcloud
+ stringData:
+ DB_PASSWORD: KSOPS_DRY_RUN_PLACEHOLDER
+ NEXTCLOUD_INSTANCEID: KSOPS_DRY_RUN_PLACEHOLDER
+ NEXTCLOUD_PASSWORDSALT: KSOPS_DRY_RUN_PLACEHOLDER
+ NEXTCLOUD_SECRET: KSOPS_DRY_RUN_PLACEHOLDER
+ S3_ACCESS_KEY: KSOPS_DRY_RUN_PLACEHOLDER
+ S3_SECRET_KEY: KSOPS_DRY_RUN_PLACEHOLDER
+ SMTP_PASSWORD: KSOPS_DRY_RUN_PLACEHOLDER
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: valkey
+ namespace: nextcloud
+ stringData:
+ default: KSOPS_DRY_RUN_PLACEHOLDER
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: nextcloud
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/name: nextcloud
+ spec:
+ type: ClusterIP
+ selector:
+ app.kubernetes.io/name: nextcloud
+ ports:
+ - name: http
+ port: 8080
+ protocol: TCP
+ targetPort: 80
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: Service
+ metadata:
+ name: valkey
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/component: primary
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/name: valkey
+ app.kubernetes.io/version: "9.0.2"
+ helm.sh/chart: valkey-0.9.4
+ spec:
+ type: ClusterIP
+ selector:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/name: valkey
+ ports:
+ - name: tcp
+ port: 6379
+ protocol: TCP
+ targetPort: tcp
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: PersistentVolumeClaim
+ metadata:
+ name: nextcloud-nextcloud
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/name: nextcloud
+ spec:
+ resources:
+ requests:
+ storage: 5Gi
+ storageClassName: longhorn
+ accessModes:
+ - ReadWriteOnce
@@ (root level) @@
! + one document added:
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: nextcloud
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/name: nextcloud
+ spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: nextcloud
+ strategy:
+ type: Recreate
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: nextcloud
+ spec:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: kubernetes.io/hostname
+ operator: In
+ values:
+ - las211.tokyotech.org
+ containers:
+ - name: nextcloud
+ image: "ghcr.io/traptitech/nextcloud:29.0.5"
+ imagePullPolicy: IfNotPresent
+ resources:
+ limits:
+ cpu: 500m
+ memory: 256Mi
+ requests:
+ cpu: 50m
+ memory: 128Mi
+ 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: base-config
+ mountPath: /var/www/html/config/base.config.php
+ subPath: base.config.php
+ envFrom:
+ - secretRef:
+ name: secret-env
+ env:
+ - name: VALKEY_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: valkey
+ key: default
+ - name: nextcloud-nginx
+ image: "library/nginx:alpine"
+ imagePullPolicy: IfNotPresent
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP
+ resources:
+ limits:
+ cpu: 100m
+ memory: 128Mi
+ requests:
+ cpu: 10m
+ memory: 32Mi
+ 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: nextcloud-nginx-config
+ mountPath: /etc/nginx/conf.d/
+ livenessProbe:
+ failureThreshold: 3
+ httpGet:
+ httpHeaders:
+ - name: Host
+ value: drive.trap.jp
+ path: /status.php
+ port: 80
+ initialDelaySeconds: 10
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ readinessProbe:
+ failureThreshold: 3
+ httpGet:
+ httpHeaders:
+ - name: Host
+ value: drive.trap.jp
+ path: /status.php
+ port: 80
+ initialDelaySeconds: 10
+ periodSeconds: 10
+ successThreshold: 1
+ timeoutSeconds: 5
+ - name: nextcloud-cron
+ image: "ghcr.io/traptitech/nextcloud:29.0.5"
+ imagePullPolicy: IfNotPresent
+ command:
+ - /cron.sh
+ resources:
+ limits:
+ cpu: 100m
+ memory: 128Mi
+ requests:
+ cpu: 10m
+ memory: 64Mi
+ 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: base-config
+ mountPath: /var/www/html/config/base.config.php
+ subPath: base.config.php
+ envFrom:
+ - secretRef:
+ name: secret-env
+ env:
+ - name: VALKEY_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: valkey
+ key: default
+ securityContext:
+ fsGroup: 82
+ volumes:
+ - name: nextcloud-main
+ persistentVolumeClaim:
+ claimName: nextcloud-nextcloud
+ - name: nextcloud-nginx-config
+ configMap:
+ name: nextcloud-nginxconfig
+ - name: base-config
+ configMap:
+ name: nextcloud-config
@@ (root level) @@
! + one document added:
+ apiVersion: apps/v1
+ kind: Deployment
+ metadata:
+ name: valkey
+ namespace: nextcloud
+ labels:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/name: valkey
+ app.kubernetes.io/version: "9.0.2"
+ helm.sh/chart: valkey-0.9.4
+ spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/name: valkey
+ strategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ annotations:
+ checksum/initconfig: 5fdddc3b28ae00152eb4fcf80ebcd11b
+ labels:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/name: valkey
+ spec:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: kubernetes.io/hostname
+ operator: In
+ values:
+ - las211.tokyotech.org
+ automountServiceAccountToken: false
+ containers:
+ - name: valkey
+ image: "docker.io/valkey/valkey:9.0.2"
+ imagePullPolicy: IfNotPresent
+ args:
+ - /data/conf/valkey.conf
+ command:
+ - valkey-server
+ env:
+ - name: VALKEY_LOGLEVEL
+ value: notice
+ ports:
+ - name: tcp
+ containerPort: 6379
+ protocol: TCP
+ resources:
+ limits:
+ cpu: 100m
+ memory: 128Mi
+ requests:
+ cpu: 50m
+ memory: 64Mi
+ volumeMounts:
+ - name: valkey-data
+ mountPath: /data
+ - name: valkey-acl
+ mountPath: /etc/valkey
+ livenessProbe:
+ exec:
+ command:
+ - sh
+ - "-c"
+ - "valkey-cli ping"
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+ startupProbe:
+ exec:
+ command:
+ - sh
+ - "-c"
+ - "valkey-cli ping"
+ initContainers:
+ - name: valkey-init
+ image: "docker.io/valkey/valkey:9.0.2"
+ imagePullPolicy: IfNotPresent
+ command:
+ - /scripts/init.sh
+ volumeMounts:
+ - name: valkey-data
+ mountPath: /data
+ - name: scripts
+ mountPath: /scripts
+ - name: valkey-acl
+ mountPath: /etc/valkey
+ - name: valkey-users-secret
+ mountPath: /valkey-users-secret
+ readOnly: true
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - ALL
+ readOnlyRootFilesystem: true
+ runAsNonRoot: true
+ runAsUser: 1000
+ securityContext:
+ fsGroup: 1000
+ runAsGroup: 1000
+ runAsUser: 1000
+ seccompProfile:
+ type: RuntimeDefault
+ serviceAccountName: valkey
+ volumes:
+ - name: scripts
+ configMap:
+ name: valkey-init-scripts
+ defaultMode: 365
+ - name: valkey-acl
+ emptyDir:
+ medium: Memory
+ - name: valkey-users-secret
+ secret:
+ defaultMode: 256
+ secretName: valkey
+ - name: valkey-data
+ emptyDir: {}
@@ (root level) @@
! + one document added:
+ apiVersion: cert-manager.io/v1
+ kind: Certificate
+ metadata:
+ name: nextcloud-tls
+ namespace: nextcloud
+ spec:
+ dnsNames:
+ - drive.trap.jp
+ duration: 2160h0m0s
+ issuerRef:
+ name: dns-cluster-issuer
+ kind: ClusterIssuer
+ renewBefore: 720h0m0s
+ secretName: nextcloud-tls
@@ (root level) @@
! + one document added:
+ apiVersion: networking.k8s.io/v1
+ kind: NetworkPolicy
+ metadata:
+ name: valkey
+ namespace: nextcloud
+ spec:
+ ingress:
+ - from:
+ - podSelector:
+ matchLabels:
+ app.kubernetes.io/name: nextcloud
+ podSelector:
+ matchLabels:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/name: valkey
+ policyTypes:
+ - Ingress
@@ (root level) @@
! + one document added:
+ apiVersion: traefik.io/v1alpha1
+ kind: IngressRoute
+ metadata:
+ name: nextcloud
+ namespace: nextcloud
+ spec:
+ entryPoints:
+ - websecure
+ routes:
+ - kind: Rule
+ match: Host(`drive.trap.jp`)
+ services:
+ - name: nextcloud
+ port: 8080
+ tls:
+ secretName: nextcloud-tls
@@ (root level) @@
! + one document added:
+ apiVersion: v1
+ kind: Pod
+ metadata:
+ name: valkey-test-auth-existing
+ namespace: nextcloud
+ annotations:
+ helm.sh/hook: test
+ helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded"
+ labels:
+ app.kubernetes.io/instance: valkey
+ app.kubernetes.io/managed-by: Helm
+ app.kubernetes.io/name: valkey
+ app.kubernetes.io/version: "9.0.2"
+ helm.sh/chart: valkey-0.9.4
+ spec:
+ containers:
+ - name: test-auth
+ image: "docker.io/valkey/valkey:9.0.2"
+ command:
+ - sh
+ - "-c"
+ - |
+ set -e
+ echo "Testing authentication with usersExistingSecret..."
+ TLS_FLAGS=""
+
+ # Test basic connection (no auth - will fail if auth is properly configured)
+ PING_RESULT=$(valkey-cli -h valkey -p 6379 $TLS_FLAGS PING 2>&1 || true)
+ if [ "$PING_RESULT" = "PONG" ]; then
+ echo "✗ Authentication test failed: server allows unauthenticated access"
+ exit 1
+ fi
+
+ echo "✓ Authentication is enforced (unauthenticated access denied)"
+ echo "✓ Received expected error: $PING_RESULT"
+ echo "⚠ Manual verification recommended for usersExistingSecret configuration"
+ exit 0
+
+ volumeMounts:
+ - name: valkey-users-secret
+ mountPath: /valkey-users-secret
+ readOnly: true
+ restartPolicy: Never
+ volumes:
+ - name: valkey-users-secret
+ secret:
+ secretName: valkey
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@nextcloud/deployment.yaml`:
- Around line 28-180: Add a securityContext to each container spec (containers
named "nextcloud", "nextcloud-nginx", and "nextcloud-cron") and set
allowPrivilegeEscalation: false; locate the container blocks in the deployment
manifest and insert a securityContext section under each container with
allowPrivilegeEscalation: false (you may also include related safe defaults like
runAsNonRoot: true or readOnlyRootFilesystem: true if desired, but at minimum
add allowPrivilegeEscalation: false).
In `@nextcloud/kustomization.yaml`:
- Around line 1-2: Add a top-level namespace entry to the Kustomization so all
generated resources (ksops Secrets, local resources) and the HelmRelease target
are placed consistently; specifically add the "namespace" key with the same
value used by the Helm release ("nextcloud") in the Kustomization so
ksops-generated Secret resources and the HelmRelease (target namespace
"nextcloud") are unified and no longer depend on apply-time options. Ensure the
Kustomization's namespace value matches the HelmRelease target and update any
related overlays if needed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 6d1163f4-3a5d-4148-b5e0-0c33b18303e0
📒 Files selected for processing (11)
nextcloud/certificate.yamlnextcloud/config.yamlnextcloud/deployment.yamlnextcloud/ingress-route.yamlnextcloud/ksops.yamlnextcloud/kustomization.yamlnextcloud/nginx-config.yamlnextcloud/secrets/secret-env.enc.yamlnextcloud/secrets/valkey.enc.yamlnextcloud/service.yamlnextcloud/valkey-values.yaml
| containers: | ||
| - name: nextcloud | ||
| image: ghcr.io/traptitech/nextcloud:29.0.5 | ||
| imagePullPolicy: IfNotPresent | ||
| resources: | ||
| limits: | ||
| cpu: 500m | ||
| memory: 256Mi | ||
| requests: | ||
| cpu: 50m | ||
| memory: 128Mi | ||
| env: | ||
| - name: VALKEY_PASSWORD | ||
| valueFrom: | ||
| secretKeyRef: | ||
| name: valkey | ||
| key: default | ||
| envFrom: | ||
| - secretRef: | ||
| name: secret-env | ||
| 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: /var/www/html/config/base.config.php | ||
| name: base-config | ||
| subPath: base.config.php | ||
| - name: nextcloud-nginx | ||
| image: library/nginx:alpine | ||
| imagePullPolicy: IfNotPresent | ||
| livenessProbe: | ||
| failureThreshold: 3 | ||
| httpGet: | ||
| httpHeaders: | ||
| - name: Host | ||
| value: drive.trap.jp | ||
| path: /status.php | ||
| port: 80 | ||
| initialDelaySeconds: 10 | ||
| periodSeconds: 10 | ||
| successThreshold: 1 | ||
| timeoutSeconds: 5 | ||
| ports: | ||
| - containerPort: 80 | ||
| name: http | ||
| protocol: TCP | ||
| readinessProbe: | ||
| failureThreshold: 3 | ||
| httpGet: | ||
| httpHeaders: | ||
| - name: Host | ||
| value: drive.trap.jp | ||
| path: /status.php | ||
| port: 80 | ||
| initialDelaySeconds: 10 | ||
| periodSeconds: 10 | ||
| successThreshold: 1 | ||
| timeoutSeconds: 5 | ||
| resources: | ||
| limits: | ||
| cpu: 100m | ||
| memory: 128Mi | ||
| requests: | ||
| cpu: 10m | ||
| 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/nginx/conf.d/ | ||
| name: nextcloud-nginx-config | ||
| - name: nextcloud-cron | ||
| command: | ||
| - /cron.sh | ||
| image: ghcr.io/traptitech/nextcloud:29.0.5 | ||
| imagePullPolicy: IfNotPresent | ||
| resources: | ||
| limits: | ||
| cpu: 100m | ||
| memory: 128Mi | ||
| requests: | ||
| cpu: 10m | ||
| memory: 64Mi | ||
| env: | ||
| - name: VALKEY_PASSWORD | ||
| valueFrom: | ||
| secretKeyRef: | ||
| name: valkey | ||
| key: default | ||
| envFrom: | ||
| - secretRef: | ||
| name: secret-env | ||
| 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: /var/www/html/config/base.config.php | ||
| name: base-config | ||
| subPath: base.config.php |
There was a problem hiding this comment.
各コンテナで allowPrivilegeEscalation: false を明示してください。
Line 28 以降の3コンテナすべてで securityContext が未設定で、権限昇格を防ぐ制約が入っていません。少なくとも allowPrivilegeEscalation: false は明示した方が安全です。
🔧 修正例
containers:
- name: nextcloud
+ securityContext:
+ allowPrivilegeEscalation: false
image: ghcr.io/traptitech/nextcloud:29.0.5
@@
- name: nextcloud-nginx
+ securityContext:
+ allowPrivilegeEscalation: false
image: library/nginx:alpine
@@
- name: nextcloud-cron
+ securityContext:
+ allowPrivilegeEscalation: false
command:
- /cron.sh📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| containers: | |
| - name: nextcloud | |
| image: ghcr.io/traptitech/nextcloud:29.0.5 | |
| imagePullPolicy: IfNotPresent | |
| resources: | |
| limits: | |
| cpu: 500m | |
| memory: 256Mi | |
| requests: | |
| cpu: 50m | |
| memory: 128Mi | |
| env: | |
| - name: VALKEY_PASSWORD | |
| valueFrom: | |
| secretKeyRef: | |
| name: valkey | |
| key: default | |
| envFrom: | |
| - secretRef: | |
| name: secret-env | |
| 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: /var/www/html/config/base.config.php | |
| name: base-config | |
| subPath: base.config.php | |
| - name: nextcloud-nginx | |
| image: library/nginx:alpine | |
| imagePullPolicy: IfNotPresent | |
| livenessProbe: | |
| failureThreshold: 3 | |
| httpGet: | |
| httpHeaders: | |
| - name: Host | |
| value: drive.trap.jp | |
| path: /status.php | |
| port: 80 | |
| initialDelaySeconds: 10 | |
| periodSeconds: 10 | |
| successThreshold: 1 | |
| timeoutSeconds: 5 | |
| ports: | |
| - containerPort: 80 | |
| name: http | |
| protocol: TCP | |
| readinessProbe: | |
| failureThreshold: 3 | |
| httpGet: | |
| httpHeaders: | |
| - name: Host | |
| value: drive.trap.jp | |
| path: /status.php | |
| port: 80 | |
| initialDelaySeconds: 10 | |
| periodSeconds: 10 | |
| successThreshold: 1 | |
| timeoutSeconds: 5 | |
| resources: | |
| limits: | |
| cpu: 100m | |
| memory: 128Mi | |
| requests: | |
| cpu: 10m | |
| 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/nginx/conf.d/ | |
| name: nextcloud-nginx-config | |
| - name: nextcloud-cron | |
| command: | |
| - /cron.sh | |
| image: ghcr.io/traptitech/nextcloud:29.0.5 | |
| imagePullPolicy: IfNotPresent | |
| resources: | |
| limits: | |
| cpu: 100m | |
| memory: 128Mi | |
| requests: | |
| cpu: 10m | |
| memory: 64Mi | |
| env: | |
| - name: VALKEY_PASSWORD | |
| valueFrom: | |
| secretKeyRef: | |
| name: valkey | |
| key: default | |
| envFrom: | |
| - secretRef: | |
| name: secret-env | |
| 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: /var/www/html/config/base.config.php | |
| name: base-config | |
| subPath: base.config.php | |
| containers: | |
| - name: nextcloud | |
| securityContext: | |
| allowPrivilegeEscalation: false | |
| image: ghcr.io/traptitech/nextcloud:29.0.5 | |
| imagePullPolicy: IfNotPresent | |
| resources: | |
| limits: | |
| cpu: 500m | |
| memory: 256Mi | |
| requests: | |
| cpu: 50m | |
| memory: 128Mi | |
| env: | |
| - name: VALKEY_PASSWORD | |
| valueFrom: | |
| secretKeyRef: | |
| name: valkey | |
| key: default | |
| envFrom: | |
| - secretRef: | |
| name: secret-env | |
| 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: /var/www/html/config/base.config.php | |
| name: base-config | |
| subPath: base.config.php | |
| - name: nextcloud-nginx | |
| securityContext: | |
| allowPrivilegeEscalation: false | |
| image: library/nginx:alpine | |
| imagePullPolicy: IfNotPresent | |
| livenessProbe: | |
| failureThreshold: 3 | |
| httpGet: | |
| httpHeaders: | |
| - name: Host | |
| value: drive.trap.jp | |
| path: /status.php | |
| port: 80 | |
| initialDelaySeconds: 10 | |
| periodSeconds: 10 | |
| successThreshold: 1 | |
| timeoutSeconds: 5 | |
| ports: | |
| - containerPort: 80 | |
| name: http | |
| protocol: TCP | |
| readinessProbe: | |
| failureThreshold: 3 | |
| httpGet: | |
| httpHeaders: | |
| - name: Host | |
| value: drive.trap.jp | |
| path: /status.php | |
| port: 80 | |
| initialDelaySeconds: 10 | |
| periodSeconds: 10 | |
| successThreshold: 1 | |
| timeoutSeconds: 5 | |
| resources: | |
| limits: | |
| cpu: 100m | |
| memory: 128Mi | |
| requests: | |
| cpu: 10m | |
| 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/nginx/conf.d/ | |
| name: nextcloud-nginx-config | |
| - name: nextcloud-cron | |
| securityContext: | |
| allowPrivilegeEscalation: false | |
| command: | |
| - /cron.sh | |
| image: ghcr.io/traptitech/nextcloud:29.0.5 | |
| imagePullPolicy: IfNotPresent | |
| resources: | |
| limits: | |
| cpu: 100m | |
| memory: 128Mi | |
| requests: | |
| cpu: 10m | |
| memory: 64Mi | |
| env: | |
| - name: VALKEY_PASSWORD | |
| valueFrom: | |
| secretKeyRef: | |
| name: valkey | |
| key: default | |
| envFrom: | |
| - secretRef: | |
| name: secret-env | |
| 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: /var/www/html/config/base.config.php | |
| name: base-config | |
| subPath: base.config.php |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@nextcloud/deployment.yaml` around lines 28 - 180, Add a securityContext to
each container spec (containers named "nextcloud", "nextcloud-nginx", and
"nextcloud-cron") and set allowPrivilegeEscalation: false; locate the container
blocks in the deployment manifest and insert a securityContext section under
each container with allowPrivilegeEscalation: false (you may also include
related safe defaults like runAsNonRoot: true or readOnlyRootFilesystem: true if
desired, but at minimum add allowPrivilegeEscalation: false).
| apiVersion: kustomize.config.k8s.io/v1beta1 | ||
| kind: Kustomization |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Kustomization 側で namespace を固定し、生成 Secret と Helm の配置先を統一してください。
Line 8 では Helm リリース先が nextcloud に固定されていますが、Line 1-2 にはトップレベル namespace がないため、ksops 生成リソースやローカルリソースの配置先が適用方法依存になります。ここは明示しておく方が安全です。
💡 提案 diff
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
+namespace: nextcloudAlso applies to: 4-10, 20-21
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@nextcloud/kustomization.yaml` around lines 1 - 2, Add a top-level namespace
entry to the Kustomization so all generated resources (ksops Secrets, local
resources) and the HelmRelease target are placed consistently; specifically add
the "namespace" key with the same value used by the Helm release ("nextcloud")
in the Kustomization so ksops-generated Secret resources and the HelmRelease
(target namespace "nextcloud") are unified and no longer depend on apply-time
options. Ensure the Kustomization's namespace value matches the HelmRelease
target and update any related overlays if needed.
Summary by CodeRabbit
リリースノート
New Features
Chores