Skip to content

feat: add nextcloud#1609

Merged
pirosiki197 merged 1 commit into
mainfrom
feat/nextcloud
May 22, 2026
Merged

feat: add nextcloud#1609
pirosiki197 merged 1 commit into
mainfrom
feat/nextcloud

Conversation

@pirosiki197
Copy link
Copy Markdown
Contributor

@pirosiki197 pirosiki197 commented May 14, 2026

Summary by CodeRabbit

リリースノート

  • New Features

    • セキュアなクラウドファイルストレージサービス(Nextcloud)の提供を開始しました。TLS暗号化通信、自動証明書管理、キャッシング機能により、安全かつ高速なファイルアクセスが可能になります。
  • Chores

    • Kubernetesベースのインフラストラクチャ構成を追加しました。

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

📝 Walkthrough

Walkthrough

Nextcloud の Kubernetes デプロイメント環境を新規構築。Kustomize で Valkey Helm チャート、複数マニフェストリソースを統合管理し、SOPS 暗号化シークレット、cert-manager TLS、Traefik イングレス、Nextcloud Deployment(nginx プロキシ、PHP、cron)、MySQL 接続、キャッシュ層を設定。

Changes

Nextcloud Kubernetes デプロイメントスタック

Layer / File(s) Summary
Kustomize オーケストレーション・ksops 設定管理
nextcloud/kustomization.yaml, nextcloud/ksops.yaml
Kustomization が Valkey Helm チャート(0.9.4)を nextcloud namespace に導入し、ローカルマニフェスト(deployment、service、config、nginx 設定、certificate、ingress)を参照・合成。ksops カスタムリソースが secret-env.enc.yaml と valkey.enc.yaml を暗号化対象として定義し、SOPS による復号制御を実施。
暗号化シークレット(secret-env・valkey)
nextcloud/secrets/secret-env.enc.yaml, nextcloud/secrets/valkey.enc.yaml
SOPS/age で暗号化された 2 つの Secret リソース。secret-env は Nextcloud/SMTP/S3/DB 環境変数を ENC[AES256_GCM,...] で保持。valkey は Valkey 認証パスワードを暗号化格納。各ファイルが SOPS メタデータ(recipient、mac、unencrypted_regex)を含む。
TLS・Traefik イングレス設定
nextcloud/certificate.yaml, nextcloud/ingress-route.yaml
cert-manager Certificate(nextcloud-tls)が dns-cluster-issuer から drive.trap.jp 用に 90 日有効な証明書を取得、720 時間前より更新開始。Traefik IngressRoute がホストルール drive.trap.jp で nextcloud Service:8080 へ HTTPS ルーティング(websecure エントリポイント + nextcloud-tls TLS)を実現。
Nextcloud Deployment・Service・Config
nextcloud/deployment.yaml, nextcloud/config.yaml, nextcloud/service.yaml
Deployment がレプリカ 1、Recreate 戦略、las211.tokyotech.org nodeAffinity で 3 コンテナ構成(Nextcloud・nginx・cron)を定義。secret-env・valkey シークレットから環境変数注入、PVC・ConfigMap マウント、nginx liveness/readiness probe(/status.php)、fsGroup セキュリティコンテキスト を設定。ConfigMap(nextcloud-config)は base.config.php に Nextcloud 設定(環境変数連携、trusted_domains、SMTP/SendGrid、APCu/Valkey キャッシュ、S3/Wasabi オブジェクトストレージ、MySQL 接続)を埋め込む。PersistentVolumeClaim は longhorn ストレージクラス、ReadWriteOnce、5Gi。Service(ClusterIP)が app.kubernetes.io/name:nextcloud ラベルで Pod 選択、port 8080→targetPort 80 をバインド。
Valkey キャッシュ・セッション層
nextcloud/valkey-values.yaml
Helm 値ファイルで Valkey インスタンスを構成。認証有効(usersExistingSecret: valkey)、デフォルトユーザに ACL ~* &* +@ALL 権限、nodeAffinity las211.tokyotech.org、CPU/メモリ制限(requests: 50m/64Mi、limits: 100m/128Mi)、networkPolicy で nextcloud ラベルの Pod からのみ ingress 許可。
nginx リバースプロキシ設定
nextcloud/nginx-config.yaml
ConfigMap(nextcloud-nginxconfig)に Nextcloud 用 nginx 設定 default.conf を格納。php-handler アップストリーム(127.0.0.1:9000)、実スキーム/ポート推定・アセット immutable キャッシュ制御の map、server 基本設定(listen 80、root /var/www/html、セキュリティヘッダ、client_max_body_size、gzip、X-Powered-By 隠蔽、.mjs/.wasm MIME)を定義。location ルール群で、DAV クライアント(/)、/robots.txt、/.well-known(CardDAV/CalDAV)、アクセス制限パス(.ht*、config/)の 404、.php リクエストの Nextcloud フロントコントローラへの rewrite・FastCGI パラメータ(SCRIPT_FILENAME、PATH_INFO、HTTPS フラグ)、CSS/JS/フォント等の static キャッシュ(try_files + expires)、/remote→/remote.php リダイレクト、デフォルトフォールバック($uri $uri/ /index.php$request_uri)を実装。

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • traPtitech/manifest#1560: 並行する Nextcloud TLS/イングレス構成追加—cert-manager Certificate と Traefik IngressRoute を同一 TLS シークレットに接続し、対応する ksops/Kustomize セットアップを含む。
  • traPtitech/manifest#1591: Nextcloud Deployment コンテナを ConfigMap から環境変数ロードおよび共有 secret-env Secret 参照で構成する設定に関連。
  • traPtitech/manifest#1589: Nextcloud デプロイメントスタックの同一コンポーネント—SOPS 管理の Valkey 暗号化シークレットと対応する valkey-values.yaml/Deployment 配線を異なるオーバーレイ(nextcloud vs nextcloud-dev)下で追加。

Suggested reviewers

  • Kentaro1043
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトル「feat: add nextcloud」は、Nextcloud を新規追加するという主要な変更を簡潔かつ明確に表現しており、変更セット全体の概要を適切に要約しています。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/nextcloud

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.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between ccdddf7 and c9441b4.

📒 Files selected for processing (11)
  • nextcloud/certificate.yaml
  • nextcloud/config.yaml
  • nextcloud/deployment.yaml
  • nextcloud/ingress-route.yaml
  • nextcloud/ksops.yaml
  • nextcloud/kustomization.yaml
  • nextcloud/nginx-config.yaml
  • nextcloud/secrets/secret-env.enc.yaml
  • nextcloud/secrets/valkey.enc.yaml
  • nextcloud/service.yaml
  • nextcloud/valkey-values.yaml

Comment thread nextcloud/deployment.yaml
Comment on lines +28 to +180
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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

各コンテナで 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.

Suggested change
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).

Comment on lines +1 to +2
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ 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: nextcloud

Also 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.

@Kentaro1043 Kentaro1043 self-requested a review May 18, 2026 15:38
Copy link
Copy Markdown
Collaborator

@Kentaro1043 Kentaro1043 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@pirosiki197 pirosiki197 merged commit b1ad4c4 into main May 22, 2026
6 checks passed
@pirosiki197 pirosiki197 deleted the feat/nextcloud branch May 22, 2026 11:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants