From c81083fd572ba3f833a519eb502884cb66c9e31c Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 8 Sep 2026 14:14:39 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=96=E9=83=A8Secret=E9=80=A3?= =?UTF-8?q?=E6=90=BA=EF=BC=88extraEnvFrom=20/=20extraEnv=20/=20SMTP=20exis?= =?UTF-8?q?tingSecret=EF=BC=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit helmchart/secret-manager が各ネームスペースへ配布する cred-* Secret を phpfpm 側から参照できるようにする。 - extraEnvFrom / extraEnv: 既存 Secret/ConfigMap を php-fpm コンテナへ env 注入 - smtp.auth.existingSecret / existingSecretKey: パスワードファイルだけ既存 Secret から取得 - smtp.existingMsmtprcSecret / existingMsmtprcSecretKey: 完成済み msmtprc を そのままマウント(指定時は configmap-smtp を生成せず host/port/auth.* は無視) 既定値は全て空のため既存挙動は不変。手動リリース 8.5.10-a。 --- CLAUDE.md | 22 ++++++++++++++++ Chart.yaml | 2 +- README.md | 49 +++++++++++++++++++++++++++++++++++ templates/configmap-smtp.yaml | 2 +- templates/deployment.yaml | 24 ++++++++++++++--- templates/secret-smtp.yaml | 2 +- values.yaml | 42 +++++++++++++++++++++++++++++- 7 files changed, 135 insertions(+), 8 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index e0840fa..3c653d3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -26,6 +26,28 @@ Websites 組織の各サイト(e-learn.jp / fcdomain.com / hotels / tskholding ## チャート改修履歴 +### 外部Secret連携(extraEnvFrom / extraEnv / SMTP existingSecret)を追加(2026-09-08, v8.5.10-a) + +**背景**: 別リポジトリの `helmchart/secret-manager` チャートが各ネームスペースへ配布する +`cred-<名前>` Secret(メールの msmtprc / API キー)を、phpfpm 側から参照する口が無かった +(`phpEnv` は直書きのみ、SMTP パスワードは `smtp.auth.password` 直書き+自作 Secret のみ)。 + +**修正内容**: +- `values.yaml` に `extraEnvFrom`(`envFrom` 配列)と `extraEnv`(生の env エントリ配列)を追加。 + php-fpm コンテナに既存 Secret/ConfigMap をまるごと env 注入できる。 +- `smtp.auth.existingSecret` / `existingSecretKey` を追加。チャートで msmtprc を生成しつつ + パスワードファイルだけ既存 Secret から取る。 +- `smtp.existingMsmtprcSecret` / `existingMsmtprcSecretKey` を追加。完成済み msmtprc を持つ + 既存 Secret をそのまま `/etc/smtp-config/msmtprc` としてマウント(secret-manager が生成する + `msmtprc` キーを想定)。指定時は `configmap-smtp` を生成せず host/port/auth.* は無視、 + `smtp-secrets` ボリュームも張らない(msmtprc にパスワードが内包されるため)。 +- `templates/secret-smtp.yaml` / `templates/configmap-smtp.yaml` を上記フラグで出し分け。 +- 既定値は全て空 → 既存挙動は不変(`helm template` の全シナリオで確認済み)。 +- 主アプリ(PHP 8.5.10)は変わらないため手動リリース `8.5.10-a`。 + +**対象ファイル**: `values.yaml`, `templates/deployment.yaml`, `templates/configmap-smtp.yaml`, +`templates/secret-smtp.yaml`, `Chart.yaml`, `README.md`, `CLAUDE.md` + ### php-fpm を `exec php-fpm -F` で起動しCrashLoopBackOffを修正(2026-09-06, v8.5.9-d) setup シェル末尾の `php-fpm`(シェルの子プロセス)を **`exec php-fpm -F`** に変更。selenium 有効構成(hotels)で php-fpm が `unable to bind ... '9000': Address in use` を出して永続 CrashLoopBackOff になり、nginx が非FastCGI応答を受けて全リクエスト502(`unsupported FastCGI protocol version: 60`)になる障害の修正。原因は php-fpm が setup シェルの子で、コンテナ PID1 のシェルが `SIGTERM` を子へ転送しないため、コンテナ再起動時に旧 php-fpm が残存し 9000 を握ったまま次回起動が二重 bind で失敗する自己増殖ループ。`exec` で php-fpm を PID1 にしてシグナルを直接受けさせ(停止時に 9000 を確実解放)、`-F` で `daemonize` 設定に依存せず必ずフォアグラウンド起動にした。全サイト共通で安全(コンテナで php-fpm を動かす定石)。復旧には `helm upgrade` に加え、残存プロセスを持つ既存 pod の削除が必要な場合がある。 diff --git a/Chart.yaml b/Chart.yaml index ad5ebe0..340fd23 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -2,6 +2,6 @@ apiVersion: v2 name: phpfpm description: Nginx + PHP-FPM Helm Chart with external DB and optional Selenium support type: application -version: 8.5.10 +version: 8.5.10-a appVersion: "8.5.10" icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png diff --git a/README.md b/README.md index ecee28d..40b61c0 100644 --- a/README.md +++ b/README.md @@ -196,9 +196,29 @@ PHPからPythonスクリプトを呼び出す用途(データ処理・機械 | パラメータ | 説明 | デフォルト | |-----------|------|-----------| | `phpEnv` | PHP-FPM コンテナに渡す任意の環境変数(キーと値のマップ) | `{}` | +| `extraEnvFrom` | 既存の Secret / ConfigMap をまるごと環境変数として注入(`envFrom` 配列) | `[]` | +| `extraEnv` | 個別の環境変数を追加(生の `env` エントリ配列。`valueFrom`/`secretKeyRef` 可) | `[]` | PHP 側では `$_ENV['KEY']` または `getenv('KEY')` で取得できます。 +`extraEnvFrom` は、別リポジトリの **secret-manager** チャートが各ネームスペースへ配布する +`cred-<名前>` Secret(API キー等)をそのまま読み込む用途を想定しています。認証情報の変更は +secret-manager 側を更新するだけで全プロジェクトに反映できます。 + +```yaml +extraEnvFrom: + - secretRef: + name: cred-gemini # GEMINI_API_KEY 等が丸ごと環境変数になる + - secretRef: + name: cred-openai +extraEnv: + - name: ANTHROPIC_API_KEY + valueFrom: + secretKeyRef: + name: cred-claude + key: ANTHROPIC_API_KEY +``` + ### SMTP設定 | パラメータ | 説明 | デフォルト | @@ -210,10 +230,39 @@ PHP 側では `$_ENV['KEY']` または `getenv('KEY')` で取得できます。 | `smtp.auth.enabled` | 認証有効化 | `true` | | `smtp.auth.username` | SMTPユーザー名 | `smtp-user@example.com` | | `smtp.auth.password` | SMTPパスワード | `""` (Secretで指定) | +| `smtp.auth.existingSecret` | パスワードを取得する既存 Secret 名(`smtp.auth.password` と自作 Secret の代わり) | `""` | +| `smtp.auth.existingSecretKey` | 上記 Secret 内のキー名 | `password` | +| `smtp.existingMsmtprcSecret` | 完成済み `msmtprc` を持つ既存 Secret 名。指定時はチャートの msmtprc 生成を行わず host/port/auth.* は無視(`from` のみ使用) | `""` | +| `smtp.existingMsmtprcSecretKey` | 上記 Secret 内の `msmtprc` キー名 | `msmtprc` | | `smtp.from` | 送信元メールアドレス(固定) | `noreply@example.com` | | `smtp.tls.verify` | TLS証明書検証 | `true` | | `smtp.tls.allowSelfSigned` | 自己署名証明書を許可 | `false` | +#### secret-manager チャートとの連携(メール設定の一元管理) + +**secret-manager** が `cred-gmail` などに生成する完成済み `msmtprc` をそのまま使う場合: + +```yaml +smtp: + enabled: true + from: "no-reply@your-domain.com" # PHP の sendmail_from 用に必要 + existingMsmtprcSecret: "cred-gmail" # このSecretの msmtprc キーをそのまま利用 +``` + +サーバ設定はチャート側 values に残し、パスワードだけ一元管理したい場合: + +```yaml +smtp: + enabled: true + host: "smtp.gmail.com" + port: 587 + auth: + enabled: true + username: "no-reply@your-domain.com" + existingSecret: "cred-gmail" + existingSecretKey: "SMTP_PASSWORD" +``` + ### Ingress設定 | パラメータ | 説明 | デフォルト | diff --git a/templates/configmap-smtp.yaml b/templates/configmap-smtp.yaml index b8a9553..d312857 100644 --- a/templates/configmap-smtp.yaml +++ b/templates/configmap-smtp.yaml @@ -1,4 +1,4 @@ -{{- if .Values.smtp.enabled }} +{{- if and .Values.smtp.enabled (not .Values.smtp.existingMsmtprcSecret) }} apiVersion: v1 kind: ConfigMap metadata: diff --git a/templates/deployment.yaml b/templates/deployment.yaml index 2677c42..1ee5716 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -280,7 +280,7 @@ spec: - name: smtp-config mountPath: /etc/smtp-config readOnly: true - {{- if .Values.smtp.auth.enabled }} + {{- if and .Values.smtp.auth.enabled (not .Values.smtp.existingMsmtprcSecret) }} - name: smtp-secrets mountPath: /etc/smtp-secrets readOnly: true @@ -306,6 +306,13 @@ spec: - name: {{ $key }} value: {{ $value | quote }} {{- end }} + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} {{- if .Values.selenium.enabled }} - name: selenium image: "{{ .Values.image.selenium.registry }}/{{ .Values.image.selenium.repository }}:{{ .Values.image.selenium.tag }}" @@ -340,17 +347,26 @@ spec: {{- end }} {{- if .Values.smtp.enabled }} - name: smtp-config + {{- if .Values.smtp.existingMsmtprcSecret }} + # 完成済み msmtprc を持つ既存 Secret(secret-manager の cred-* 等)を利用 + secret: + secretName: {{ .Values.smtp.existingMsmtprcSecret }} + items: + - key: {{ .Values.smtp.existingMsmtprcSecretKey | default "msmtprc" }} + path: msmtprc + {{- else }} configMap: name: {{ include "phpfpm.fullname" . }}-smtp-config items: - key: msmtprc path: msmtprc - {{- if .Values.smtp.auth.enabled }} + {{- end }} + {{- if and .Values.smtp.auth.enabled (not .Values.smtp.existingMsmtprcSecret) }} - name: smtp-secrets secret: - secretName: {{ include "phpfpm.fullname" . }}-smtp + secretName: {{ .Values.smtp.auth.existingSecret | default (printf "%s-smtp" (include "phpfpm.fullname" .)) }} items: - - key: password + - key: {{ .Values.smtp.auth.existingSecretKey | default "password" }} path: password # 0600だとSecretボリュームの所有者はroot、 # msmtpはPHP-FPMワーカー(www-data等の非root)から実行されるため読めない diff --git a/templates/secret-smtp.yaml b/templates/secret-smtp.yaml index b62b37a..2f27419 100644 --- a/templates/secret-smtp.yaml +++ b/templates/secret-smtp.yaml @@ -1,4 +1,4 @@ -{{- if .Values.smtp.enabled }} +{{- if and .Values.smtp.enabled (not .Values.smtp.existingMsmtprcSecret) (not .Values.smtp.auth.existingSecret) }} apiVersion: v1 kind: Secret metadata: diff --git a/values.yaml b/values.yaml index c1a636a..f240f1e 100644 --- a/values.yaml +++ b/values.yaml @@ -222,6 +222,15 @@ smtp: # password: "your-smtp-password" password: "" + # 【外部Secret連携】チャートで msmtprc を生成しつつ、パスワードファイルだけ + # 既存 Secret から取りたい場合に指定する。 + # 例: secret-manager チャートが配布する cred-<プロバイダ> の SMTP_PASSWORD キー + # existingSecret: "cred-gmail" + # existingSecretKey: "SMTP_PASSWORD" + # 指定時は smtp.auth.password と自作の -smtp Secret は使われない。 + existingSecret: "" + existingSecretKey: "password" + # 送信元アドレス(固定値) # PHPプログラムで mail() 関数の $additional_parameters で上書き可能 # 例: mail($to, $subject, $body, $headers, "-f user@example.com") @@ -234,6 +243,17 @@ smtp: # 自己署名証明書を許可する場合(テスト環境のみ) allowSelfSigned: false + # 【外部Secret連携】完成済みの msmtprc がまるごと入っている既存 Secret を使う。 + # 指定するとチャート内の msmtprc 生成(configmap-smtp)は行わず、 + # host / port / protocol / auth.* / tls.* は無視される(from だけ PHP の + # sendmail_from 用に使用)。 + # secret-manager チャートが cred-<プロバイダ> に生成する msmtprc キーを + # そのまま利用できる: + # existingMsmtprcSecret: "cred-gmail" + # existingMsmtprcSecretKey: "msmtprc" + existingMsmtprcSecret: "" + existingMsmtprcSecretKey: "msmtprc" + resources: {} # PHP-FPM コンテナに渡す任意の環境変数 @@ -243,4 +263,24 @@ phpEnv: {} # API_KEY: "your-api-key" # STRIPE_SECRET: "sk_live_xxxxxxxxxxxxxxxx" # REDIS_URL: "redis://localhost:6379" -# SOME_SERVICE_URL: "https://api.example.com" \ No newline at end of file +# SOME_SERVICE_URL: "https://api.example.com" + +# 既存の Secret / ConfigMap をまるごと環境変数として PHP-FPM コンテナへ注入する(envFrom)。 +# 別リポジトリの secret-manager チャートが各ネームスペースへ配布する +# cred-<名前> Secret(API キー等)をそのまま読み込む用途を想定。 +# 変更は secret-manager 側を更新するだけで全プロジェクトに反映できる。 +extraEnvFrom: [] +# - secretRef: +# name: cred-gemini +# - secretRef: +# name: cred-openai +# - configMapRef: +# name: some-shared-config + +# 個別の環境変数を追加する(生の env エントリ配列。value / valueFrom(secretKeyRef 等) 使用可)。 +extraEnv: [] +# - name: OPENAI_API_KEY +# valueFrom: +# secretKeyRef: +# name: cred-openai +# key: OPENAI_API_KEY \ No newline at end of file