Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ae463fc49 | ||
|
|
b872dd4bd9 | ||
|
|
6de85b9ad4 | ||
|
|
eb3eef601a | ||
|
|
7c5e9e44c8 | ||
|
|
e9428c6448 | ||
|
|
8f1b050bb2 | ||
|
|
e27f02992f | ||
|
|
1be71b95e4 | ||
|
|
3d384ab72e |
@@ -0,0 +1,7 @@
|
||||
---
|
||||
trigger: always_on
|
||||
description: Read the CLAUDE.md hierarchy via GEMINI.md before doing anything in this workspace
|
||||
---
|
||||
|
||||
最初に、このディレクトリの `GEMINI.md` を読み、そこに列挙された CLAUDE.md を上から順にすべて読んで従うこと。
|
||||
Read `GEMINI.md` in this directory first, then read and follow every CLAUDE.md it lists, in order.
|
||||
@@ -0,0 +1,58 @@
|
||||
# Changelog - Version 8.5.8-a
|
||||
|
||||
## 新機能
|
||||
|
||||
### Python導入オプションの追加
|
||||
|
||||
PHPからPythonスクリプトを呼び出す用途(データ処理・機械学習ライブラリの利用など)向けに、`values.yaml` の設定だけでPython仮想環境(venv)を導入できるようにしました。既存のComposerサポートと同じ設計方針を踏襲しています。
|
||||
|
||||
#### 主な変更点
|
||||
|
||||
1. **values.yaml**
|
||||
- `python` セクションを新設
|
||||
- `enabled`: Python有効化
|
||||
- `venvDir`: venv導入先(デフォルト `/venv` — Webルート外かつPVCにマウントされない使い捨て領域)
|
||||
- `packages` / `useRequirementsTxt` / `requirementsTxt`: pipパッケージ指定方法(Composerの `packages` / `useComposerJson` と同じ構造)
|
||||
- `installOptions`: pip installオプション(デフォルト `--no-cache-dir`)
|
||||
- `additionalApkPackages`: ネイティブ拡張ビルド用の追加APKパッケージ
|
||||
|
||||
2. **templates/deployment.yaml**
|
||||
- `python.enabled` 時に `python3` / `py3-pip` をAPKでインストール
|
||||
- `python3 -m venv` で仮想環境を構築
|
||||
- `useRequirementsTxt` / `packages` に応じてpipインストールを実行
|
||||
- `requirementsTxt` の複数行内容は `trim | nindent 14` で展開(v8.5.6-d のComposer修正と同じ手法でYAML破壊を回避)
|
||||
|
||||
3. **README.md**
|
||||
- パラメータ表・使用例(例12)を追加
|
||||
- Alpine(musl)向け事前ビルドwheelが無いパッケージ(numpy等)はビルドに時間がかかる旨の注意書きを追加
|
||||
|
||||
## 設計方針(Composerとの一貫性)
|
||||
|
||||
- デフォルトの `/venv` はPVCにマウントされず、**Pod再起動のたびにクリーンな環境へ再構築される使い捨て領域**です。不正アクセスで書き込まれても再起動で消えます。
|
||||
- 永続化したい場合は `python.venvDir` に `/var/www` 配下のパスを指定してください(例: `/var/www/venv`)。
|
||||
|
||||
## 使用例
|
||||
|
||||
```yaml
|
||||
python:
|
||||
enabled: true
|
||||
useRequirementsTxt: true
|
||||
requirementsTxt: |
|
||||
requests>=2.31.0
|
||||
pandas>=2.0.0
|
||||
```
|
||||
|
||||
PHPからの呼び出し:
|
||||
|
||||
```php
|
||||
exec('/venv/bin/python3 /var/www/scripts/process.py 2>&1', $output, $exitCode);
|
||||
```
|
||||
|
||||
## 互換性
|
||||
|
||||
- デフォルトは `enabled: false` のため、既存環境への影響はありません。
|
||||
|
||||
---
|
||||
|
||||
**リリース日**: 2026-07-19
|
||||
**担当**: プロサーバーエンジニア(Claude)
|
||||
@@ -0,0 +1,35 @@
|
||||
# Changelog - Version 8.5.9-a
|
||||
|
||||
## 修正
|
||||
|
||||
### sitemap.xml のContent-Typeを明示的に指定
|
||||
|
||||
`/sitemap.xml`(静的ファイル)へのアクセス時、標準の `mime.types` では `.xml` が `text/xml` 扱いとなり `charset` が付与されないため、ブラウザやGoogle Search Consoleなどのツールが正しく解釈できない場合がありました。
|
||||
|
||||
**対応**: `templates/configmap.yaml` のnginx設定に `location = /sitemap.xml` を追加し、`types { } default_type "application/xml; charset=utf-8";` によって明示的にContent-Typeを指定するようにしました。
|
||||
|
||||
```nginx
|
||||
location = /sitemap.xml {
|
||||
types { }
|
||||
default_type "application/xml; charset=utf-8";
|
||||
try_files $uri =404;
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事項
|
||||
|
||||
- この対応は `/sitemap.xml` が**静的ファイル**として `html/` 直下に配置されている場合に適用されます。
|
||||
- PHPで動的に生成する場合(`/index.php` へのフォールバック経由)は、nginxのこの設定は適用されません。PHP側で `header('Content-Type: application/xml; charset=utf-8');` を明示的に指定してください。
|
||||
- 設定不要・常時有効です(values.yamlへの変更はありません)。ファイルが存在しない場合は従来どおり404を返します。
|
||||
|
||||
## アップグレード手順
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-a -f values.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**リリース日**: 2026-08-06
|
||||
**担当**: プロサーバーエンジニア(Claude)
|
||||
@@ -0,0 +1,52 @@
|
||||
# Changelog - Version 8.5.9-b
|
||||
|
||||
## 新機能
|
||||
|
||||
### アップロード最大サイズを values.yaml で設定可能に
|
||||
|
||||
大きなファイルのアップロードが失敗する問題(nginxとPHPそれぞれに別々のアップロード上限があり、片方だけ上げても失敗する)に対応するため、`uploadMaxSize` パラメータを新設しました。
|
||||
|
||||
#### 主な変更点
|
||||
|
||||
1. **values.yaml**
|
||||
- `uploadMaxSize: "100m"` を追加(デフォルト100MB)
|
||||
|
||||
2. **templates/configmap.yaml**
|
||||
- nginx設定に `client_max_body_size {{ .Values.uploadMaxSize }};` を追加
|
||||
|
||||
3. **templates/deployment.yaml**
|
||||
- PHP-FPM起動時に `/usr/local/etc/php/conf.d/99-uploads.ini` を生成し、
|
||||
`upload_max_filesize` / `post_max_size` に同じ値を設定
|
||||
- 常時適用(他機能の有効化状態に依存しない)
|
||||
|
||||
4. **README.md**
|
||||
- パラメータ表と、nginx/PHP両方に反映される設計についての注記を追加
|
||||
|
||||
## 背景
|
||||
|
||||
nginxの `client_max_body_size` だけを上げても、PHPには独自の `upload_max_filesize`(デフォルト2M)/ `post_max_size`(デフォルト8M)という別の上限があり、nginxを通過した後にPHP側で無言で失敗するケースがありました。この2つを同じ値で連動させることで、設定漏れによる失敗を構造的に防ぎます。
|
||||
|
||||
## 使用例
|
||||
|
||||
```yaml
|
||||
uploadMaxSize: "100m"
|
||||
# 大きな動画ファイルなどを扱う場合
|
||||
# uploadMaxSize: "500m"
|
||||
```
|
||||
|
||||
## 互換性
|
||||
|
||||
- デフォルト値は `100m`(従来の暗黙の上限より大幅に緩和)。既存よりアップロード可能サイズが大きくなる方向の変更のため、既存環境への悪影響はありません。
|
||||
- 大きなファイルをPHP側でメモリに読み込んで処理する場合、`memory_limit`(デフォルト128M程度)が別途不足する可能性がある点に注意してください。
|
||||
|
||||
## アップグレード手順
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-b -f values.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**リリース日**: 2026-08-06
|
||||
**担当**: プロサーバーエンジニア(Claude)
|
||||
@@ -0,0 +1,40 @@
|
||||
# Changelog - Version 8.5.9-c
|
||||
|
||||
## 新機能
|
||||
|
||||
### Ingressのアップロードサイズ上限も uploadMaxSize に自動連動
|
||||
|
||||
v8.5.9-b で `uploadMaxSize` によりnginx/PHPのアップロード上限を連動させましたが、`ingress.enabled: true` で運用している場合、Ingressコントローラー(ingress-nginx)にも独自のリクエストサイズ上限(デフォルト1MB)があり、そこで先に弾かれてしまうケースが残っていました。
|
||||
|
||||
**対応**: `templates/ingress.yaml` で、`ingress.annotations` に `nginx.ingress.kubernetes.io/proxy-body-size` が明示指定されていない場合、`uploadMaxSize` の値を自動的に付与するようにしました。ユーザーが `ingress.annotations` に明示的に指定した場合はそちらが優先されます。
|
||||
|
||||
```yaml
|
||||
# 何も指定しなくても、Ingressにも uploadMaxSize の値(デフォルト100m)が反映される
|
||||
uploadMaxSize: "100m"
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
これにより、`uploadMaxSize` 1箇所の設定で以下すべてに反映されます:
|
||||
|
||||
- nginx(Podコンテナ内)の `client_max_body_size`
|
||||
- PHPの `upload_max_filesize` / `post_max_size`
|
||||
- ingress-nginxの `nginx.ingress.kubernetes.io/proxy-body-size`
|
||||
|
||||
## 互換性
|
||||
|
||||
- Ingressコントローラーがingress-nginx以外の場合、このアノテーションは無視されます。該当コントローラー向けの設定を `ingress.annotations` に明示的に指定してください。
|
||||
- 既存で `ingress.annotations` に独自の `proxy-body-size` を指定している場合、その値がそのまま優先されるため影響ありません。
|
||||
|
||||
## アップグレード手順
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-c -f values.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**リリース日**: 2026-08-06
|
||||
**担当**: プロサーバーエンジニア(Claude)
|
||||
@@ -0,0 +1,54 @@
|
||||
# Changelog - Version 8.5.9-d
|
||||
|
||||
## 不具合修正
|
||||
|
||||
### php-fpm を `exec php-fpm -F` で起動(CrashLoopBackOff / 502 の修正)
|
||||
|
||||
php-fpm コンテナの起動コマンドを、setup シェルスクリプト末尾の `php-fpm`(シェルの子プロセスとしてフォアグラウンド起動)から **`exec php-fpm -F`** に変更しました。
|
||||
|
||||
**背景(実際に発生した障害)**
|
||||
|
||||
`selenium.enabled: true` の構成(例: hotels / booking.e-stay.jp)で、php-fpm コンテナが次のエラーで永続的に CrashLoopBackOff に陥る事象が発生しました。
|
||||
|
||||
```
|
||||
[NOTICE] Failed implicitly binding to ::, retrying with 0.0.0.0
|
||||
[ERROR] unable to bind listening socket for address '9000': Address in use (98)
|
||||
[ERROR] FPM initialization failed
|
||||
```
|
||||
|
||||
php-fpm が 9000 を bind できず起動に失敗するため、nginx が `fastcgi_pass 127.0.0.1:9000` に投げても FastCGI ではない応答が返り、`upstream sent unsupported FastCGI protocol version: 60` として **全リクエストが 502** になります(`60` = `<`、= 9000 を握っている別プロセスが HTML 等を返している)。
|
||||
|
||||
**原因**
|
||||
|
||||
起動コマンドが `sh -c "<setup> ... php-fpm"` の形で、**php-fpm が setup シェルの子プロセス**になっていた。コンテナ PID1 はシェルであり、シェルは既定で受け取った `SIGTERM` を子プロセスへ転送しない。そのためコンテナ(php-fpm コンテナのみ)の再起動時に、PID1 のシェルだけが先に終了し、**旧 php-fpm が一時的に残存して 9000 を握ったまま**になることがある。この状態で新しい php-fpm が起動すると `Address in use` で失敗 → 再起動 → 同じ残存 → という自己増殖ループに入り、CrashLoopBackOff から復帰できなくなる。selenium サイドカーは 9000 を使用しておらず無関係(別 pod でのポート占有調査でも確認済み)。
|
||||
|
||||
**対応**
|
||||
|
||||
- `exec php-fpm` … php-fpm が setup シェルを置き換えて**コンテナの PID1 になる**。kubelet からの `SIGTERM`/`SIGKILL` が php-fpm 本体へ直接届き、停止時に 9000 が確実に解放されるため、次回起動での二重 bind が起きない。
|
||||
- `-F`(`--nodaemonize`)… php-fpm.conf の `daemonize` 設定に依存せず、必ずフォアグラウンドで起動する(master が背後に残る事故を防ぐ)。
|
||||
|
||||
これは全サイト共通で安全な変更(コンテナ内で php-fpm を動かす際の定石)であり、既存の正常稼働サイトの挙動は変わりません。
|
||||
|
||||
**復旧手順(重要)**
|
||||
|
||||
チャートを `8.5.9-d` に上げても、既存 pod のネットワーク名前空間に残存プロセスがある場合は、その pod を作り直してクリーンな状態にする必要があります。`helm upgrade` で新しい pod に置き換わりますが、置き換わらない場合は crashloop 中の pod を明示的に削除してください。
|
||||
|
||||
```bash
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-d -f values.yaml
|
||||
# 置き換わらない場合:
|
||||
kubectl delete pod -n <namespace> -l app.kubernetes.io/name=phpfpm
|
||||
```
|
||||
|
||||
**対象ファイル**: `templates/deployment.yaml`, `Chart.yaml`, `README.md`, `CLAUDE.md`, `CHANGELOG-8.5.9-d.md`
|
||||
|
||||
## アップグレード手順
|
||||
|
||||
```bash
|
||||
helm repo update
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-d -f values.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**リリース日**: 2026-09-06
|
||||
**担当**: プロサーバーエンジニア(Claude)
|
||||
@@ -1,27 +1,63 @@
|
||||
# CLAUDE.md — phpfpm Helm Chart
|
||||
|
||||
> **共通ルール(要約)** — 詳細は `P:\Claude\CLAUDE.md`(全体共通)と `P:\Claude\HelmChart\CLAUDE.md`(Helm チャート共通: リリースフロー・ワークフロー・Gitea Secrets・クラスタ構成)を参照。
|
||||
> 作業前に pull / 機能変更時は README 更新 / 作業単位ごとに commit → push まで / コミットに AI クレジットを付けない / pull で入った変更を revert しない / Helm・PHP はローカル実行不可(Python のみ可)。
|
||||
|
||||
## リポジトリ概要
|
||||
|
||||
Raspberry Pi などのベアメタルで稼働することを想定した、Kubernetes 上で動作する Nginx + PHP-FPM の Helm チャート。
|
||||
Websites 組織の各サイト(e-learn.jp / fcdomain.com / hotels / tskholding.com など)はこのチャートでデプロイされる。
|
||||
|
||||
- **Gitea リポジトリ**: `ssh://git@192.168.9.65/helmchart/phpfpm`
|
||||
- **Helm リポジトリ**: `https://git.cafepieters.com/api/packages/helmchart/helm`
|
||||
- **主アプリ**: PHP(`docker.io/php:<tag>-fpm-alpine`)。サブアプリ: nginx
|
||||
|
||||
## 実行環境について
|
||||
|
||||
**PHP の実行環境(インタープリタ)はこのリポジトリには含まれていない。**
|
||||
チャートは `docker.io/php:<tag>-fpm-alpine` の公式イメージを Kubernetes 上で起動するものであり、PHP コードそのものは PVC(`/var/www/html`)に別途配置する必要がある。
|
||||
|
||||
## Git コミット情報
|
||||
## 設計上の注意(既知の落とし穴)
|
||||
|
||||
| 項目 | 値 |
|
||||
|------|-----|
|
||||
| 名前 | Claude |
|
||||
| メール | claude@cafepieters.com |
|
||||
| SSH キー | `P:\Claude\.ssh\id_claude` |
|
||||
- `templates/configmap.yaml` が実際に使われている nginx 設定。`templates/configmap-nginx.yaml` は `.Values.nginx.enabled` が values.yaml に存在せず常に未出力の**死んだファイル**なので注意。
|
||||
- PVC はルートを `/var/www` にマウントする(`html/` が公開フォルダ、それ以外は非公開)。`/composer` は Pod 再起動ごとにクリーン再構築される使い捨て領域。
|
||||
- `uploadMaxSize` 1箇所で nginx `client_max_body_size`・PHP `upload_max_filesize`/`post_max_size`・Ingress `proxy-body-size` の3箇所が連動する。
|
||||
- Secret / ConfigMap をファイルとして PHP-FPM ワーカー(`www-data`)から読ませる場合、権限は `0644` にする(`0600` だと読めない)。
|
||||
|
||||
## チャート改修履歴
|
||||
|
||||
### 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 の削除が必要な場合がある。
|
||||
|
||||
**対象ファイル**: `templates/deployment.yaml`, `Chart.yaml`, `README.md`, `CLAUDE.md`, `CHANGELOG-8.5.9-d.md`
|
||||
|
||||
### Ingressのproxy-body-sizeもuploadMaxSizeに連動(2026-08-06, v8.5.9-c)
|
||||
|
||||
v8.5.9-bのフォローアップ。`templates/ingress.yaml` で `merge (deepCopy .Values.ingress.annotations) (dict "nginx.ingress.kubernetes.io/proxy-body-size" .Values.uploadMaxSize)` を使い、ユーザーが明示指定していなければ `uploadMaxSize` をIngressの `proxy-body-size` にも自動反映。明示指定があればそちらが優先(sprigのmergeはdst=ユーザー指定annotationsが優先、srcのデフォルト値は不足分のみ補う)。これで `uploadMaxSize` 1箇所でnginx・PHP・Ingressの3箇所すべてが揃う。
|
||||
|
||||
**対象ファイル**: `templates/ingress.yaml`, `values.yaml`, `README.md`, `Chart.yaml`, `CHANGELOG-8.5.9-c.md`
|
||||
|
||||
### uploadMaxSize の追加(2026-08-06, v8.5.9-b)
|
||||
|
||||
nginxの `client_max_body_size` とPHPの `upload_max_filesize`/`post_max_size` を1つの `uploadMaxSize`(デフォルト `"100m"`)で連動させるパラメータを追加。片方だけ上げてももう片方の上限でアップロードが無言で失敗する問題への対応。PHP側は起動時に `/usr/local/etc/php/conf.d/99-uploads.ini` を常時生成(他機能の有効/無効に依存しない)。memory_limitは対象外(別途必要なら将来検討)。
|
||||
|
||||
**対象ファイル**: `values.yaml`, `templates/configmap.yaml`, `templates/deployment.yaml`, `README.md`, `Chart.yaml`, `CHANGELOG-8.5.9-b.md`
|
||||
|
||||
### sitemap.xml のContent-Type明示(2026-08-06, v8.5.9-a)
|
||||
|
||||
`templates/configmap.yaml` に `location = /sitemap.xml { types { } default_type "application/xml; charset=utf-8"; ... }` を追加。標準mime.typesでは `.xml` が `text/xml` 扱いでcharset無しになる問題への対応。静的ファイルの場合のみ有効、PHP動的生成には効かない(PHP側でheader()指定が必要)。設定不要・常時有効。
|
||||
|
||||
**対象ファイル**: `templates/configmap.yaml`, `README.md`, `Chart.yaml`, `CHANGELOG-8.5.9-a.md`
|
||||
|
||||
### Python導入オプションの追加(2026-07-19, v8.5.8-a)
|
||||
|
||||
`python` セクションを新設し、`values.yaml` の設定だけでPython仮想環境(venv)を導入可能にした。Composerと同じ設計方針(デフォルト導入先 `/venv` はPVC非マウントの使い捨て領域、`packages`/`useRequirementsTxt`の二択、`additionalApkPackages`でネイティブ拡張ビルド対応)。requirements.txtの展開は `trim | nindent 14`(v8.5.6-dのバグ修正と同じ手法)。PHPからは `exec('/venv/bin/python3 script.py')` で呼び出す。
|
||||
|
||||
なお、この改修中に自動更新ワークフローがPHP 8.5.8へのフルリリース(v8.5.8)を実行したため、本機能はそのタグの上に手動リリース `8.5.8-a` として適用した。
|
||||
|
||||
**対象ファイル**: `values.yaml`, `templates/deployment.yaml`, `README.md`, `Chart.yaml`, `CHANGELOG-8.5.8-a.md`
|
||||
|
||||
### /etc/msmtprc の権限を0600→0644に修正(2026-07-19, v8.5.6-g)
|
||||
|
||||
v8.5.6-f のフォローアップ。`/etc/smtp-secrets/password` の権限修正だけでは不十分で、起動スクリプトが `cp` 後に `chmod 600` していた `/etc/msmtprc` 自体もrootのみ読み取り可のままだった(msmtp: account default not found, exit:78)。`chmod 644` に変更。msmtprcには平文パスワードは含まれない(passwordeval経由で別ファイル参照)ため実害なし。
|
||||
|
||||
+2
-2
@@ -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.8
|
||||
appVersion: "8.5.8"
|
||||
version: 8.5.10
|
||||
appVersion: "8.5.10"
|
||||
icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# GEMINI.md — Antigravity (Gemini) 用エントリポイント(HelmChart\phpfpm)
|
||||
|
||||
このディレクトリのルールはすべて **`CLAUDE.md`** に記載されている。本ファイルにはルール本文を書かず、読むべき CLAUDE.md への参照だけを置く(正本は常に CLAUDE.md)。
|
||||
|
||||
## 必ず最初に実行すること
|
||||
|
||||
以下のファイルを**上から順に**読み込み、すべての指示に従うこと。上位ほど広い範囲に適用される共通ルールで、下位は上位を前提とした補足・例外である。
|
||||
|
||||
1. `P:\Claude\CLAUDE.md` — 全組織共通ルール(Git 運用・コミット書式・実行環境・情報記載の原則)
|
||||
2. `P:\Claude\HelmChart\CLAUDE.md` — HelmChart 組織共通ルール
|
||||
3. `P:\Claude\HelmChart\phpfpm\CLAUDE.md` — phpfpm リポジトリ固有ルール(このディレクトリ)
|
||||
|
||||
> Antigravity はワークスペース(または git ルート)直下のルールしか自動で読まず、親フォルダを遡らない。そのため上位階層のパスをここに明示している。`P:\Claude` はクラウド同期されており、デスクトップ・ノート PC とも同じパスで存在する。
|
||||
|
||||
## 読み替え
|
||||
|
||||
- CLAUDE.md 中の「Claude」「Claude Code」は、Antigravity で作業する場合は Gemini 自身のことと読み替える。
|
||||
- Git のコミット者は Antigravity でも `user.name = Claude` / `user.email = claude@cafepieters.com` のまま使う(変更しない)。コミットメッセージに AI クレジットを付けない。
|
||||
- Claude Code 固有の機能(`.claude/` 設定、スキル、メモリ等)に関する記述は無視してよい。
|
||||
|
||||
## 保守ルール
|
||||
|
||||
- ルールの追加・変更は **CLAUDE.md にのみ**行う。本ファイルと `.agents/rules/claude-md.md` は参照だけを保持し、内容を増やさない。
|
||||
- CLAUDE.md を新しいディレクトリに追加したときは、同じ形式の `GEMINI.md` と `.agents/rules/claude-md.md` も併置する。
|
||||
@@ -108,6 +108,17 @@ kubectl logs -l app.kubernetes.io/name=phpfpm -c nginx
|
||||
| `image.nginx.tag` | Nginxバージョン | `1.29.4-alpine-perl` |
|
||||
| `service.type` | Serviceタイプ | `LoadBalancer` |
|
||||
| `service.port` | Serviceポート | `80` |
|
||||
| `uploadMaxSize` | アップロード最大サイズ(nginx/PHP両方に反映) | `"100m"` |
|
||||
|
||||
> **📌 アップロードサイズ上限について**
|
||||
> `uploadMaxSize` の値は、以下**すべて**に同時に反映されます。どれか一つでも小さいと、そこで上限に達して失敗するため、この1つの値で揃える設計です。
|
||||
> - nginx(Podコンテナ内)の `client_max_body_size`
|
||||
> - PHPの `upload_max_filesize` / `post_max_size`
|
||||
> - `ingress.enabled: true` の場合、ingress-nginxの `nginx.ingress.kubernetes.io/proxy-body-size`(明示指定があればそちらが優先)
|
||||
>
|
||||
> 単位は `k` / `m` / `g`(大文字小文字問わず)が使用できます(例: `"200m"`, `"1g"`)。
|
||||
>
|
||||
> 大きなファイルをPHP側でメモリに読み込んで処理する場合は、PHPの `memory_limit`(デフォルト128M程度)が不足する可能性があります。その場合は `phpEnv` 等ではなくカスタムイメージ、または将来的な設定拡張で対応してください。
|
||||
|
||||
### 永続化ストレージ
|
||||
|
||||
@@ -138,6 +149,30 @@ kubectl logs -l app.kubernetes.io/name=phpfpm -c nginx
|
||||
| `composer.additionalPhpExtensions` | 追加PHP拡張 | `[]` |
|
||||
| `composer.additionalApkPackages` | 追加APKパッケージ | `[]` |
|
||||
|
||||
### Python設定(オプション)
|
||||
|
||||
PHPからPythonスクリプトを呼び出す用途(データ処理・機械学習ライブラリの利用など)向けに、Python仮想環境(venv)を導入できます。
|
||||
|
||||
| パラメータ | 説明 | デフォルト |
|
||||
|-----------|------|-----------|
|
||||
| `python.enabled` | Python有効化 | `false` |
|
||||
| `python.venvDir` | venv導入先ディレクトリ(`{venvDir}/bin/python3`) | `"/venv"` |
|
||||
| `python.packages` | pipでインストールするパッケージ | `[]` |
|
||||
| `python.useRequirementsTxt` | requirements.txt使用 | `false` |
|
||||
| `python.requirementsTxt` | requirements.txtの内容 | `"requests>=2.31.0"` |
|
||||
| `python.installOptions` | pip installオプション | `"--no-cache-dir"` |
|
||||
| `python.additionalApkPackages` | 追加APKパッケージ(ネイティブ拡張のビルド用) | `[]` |
|
||||
|
||||
> **📌 Python導入先について**
|
||||
> Composerと同様、デフォルトの `/venv` は**Webルート外かつPVCにマウントされない使い捨て領域**です。Pod再起動のたびにクリーンな仮想環境へ再構築されます。PVCに永続化したい場合は `python.venvDir` に `/var/www` 配下(例: `/var/www/venv`)を指定してください。
|
||||
>
|
||||
> PHPコードからは `exec()` 等で呼び出します:
|
||||
> ```php
|
||||
> exec('/venv/bin/python3 /var/www/scripts/process.py 2>&1', $output, $exitCode);
|
||||
> ```
|
||||
>
|
||||
> **⚠️ 注意**: `numpy` や `pillow` など、Alpine(musl)向けの事前ビルド済みwheelが無いパッケージは、Pod起動のたびにソースからビルドされ、Raspberry Pi等のARM環境では起動に数分〜十数分かかる場合があります。ビルドに必要なパッケージ(`gcc`, `musl-dev`, `python3-dev` 等)は `python.additionalApkPackages` に指定してください。永続化(`venvDir`をPVC配下に)すれば再起動のたびの再ビルドを回避できますが、使い捨てによるクリーン環境維持のメリットとのトレードオフになります。
|
||||
|
||||
### Selenium設定
|
||||
|
||||
| パラメータ | 説明 | デフォルト |
|
||||
@@ -189,6 +224,9 @@ PHP 側では `$_ENV['KEY']` または `getenv('KEY')` で取得できます。
|
||||
| `ingress.hosts` | ホスト設定 | `[{host: "example.tld"}]` |
|
||||
| `ingress.tls` | TLS設定 | `[]` |
|
||||
|
||||
> **📌 Ingressのアップロードサイズ上限**
|
||||
> `ingress.enabled: true` の場合、`nginx.ingress.kubernetes.io/proxy-body-size` アノテーションが `uploadMaxSize` の値で**自動的に**付与されます(明示的に `ingress.annotations` へ指定した場合はそちらが優先されます)。Ingressコントローラーがnginx以外の場合は、`ingress.annotations` にそのコントローラー向けの上限設定を明示的に指定してください。
|
||||
|
||||
### Nginx設定
|
||||
|
||||
| パラメータ | 説明 | デフォルト |
|
||||
@@ -201,6 +239,10 @@ PHP 側では `$_ENV['KEY']` または `getenv('KEY')` で取得できます。
|
||||
| `nginx.forwardRealIP.trustedProxies` | 信頼するプロキシネットワーク | `["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]` |
|
||||
| `nginx.forwardRealIP.additionalTrustedProxies` | 追加の信頼プロキシ | `[]` |
|
||||
|
||||
> **📌 sitemap.xml のContent-Type**
|
||||
> `/sitemap.xml`(静的ファイルとして配置した場合)は、常に `Content-Type: application/xml; charset=utf-8` で配信されます。標準の `mime.types` では `.xml` が `text/xml` 扱いでcharsetが付かず、ブラウザやGoogle Search Consoleなどのツールが正しく解釈できない場合があるための組み込み対応です(設定不要、常時有効)。
|
||||
> なお、PHPで動的に生成する場合はこの設定は適用されません(PHP側で `header('Content-Type: application/xml; charset=utf-8');` を指定してください)。
|
||||
|
||||
## 使用例
|
||||
|
||||
### 例1: シンプルなPHPアプリケーション
|
||||
@@ -696,6 +738,37 @@ $headers = [
|
||||
SmtpConfig::mail($to, $subject, $body, $headers, 'custom@your-domain.com');
|
||||
```
|
||||
|
||||
### 例12: Python連携(requirements.txtを使用)
|
||||
|
||||
PHPからPythonスクリプトを呼び出してデータ処理を行う設定です。
|
||||
|
||||
```yaml
|
||||
# values.yaml
|
||||
python:
|
||||
enabled: true
|
||||
useRequirementsTxt: true
|
||||
requirementsTxt: |
|
||||
requests>=2.31.0
|
||||
pandas>=2.0.0
|
||||
installOptions: "--no-cache-dir"
|
||||
```
|
||||
|
||||
**PHPでの使用例**:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$script = escapeshellarg('/var/www/scripts/process.py');
|
||||
exec("/venv/bin/python3 {$script} 2>&1", $output, $exitCode);
|
||||
|
||||
if ($exitCode === 0) {
|
||||
echo implode("\n", $output);
|
||||
} else {
|
||||
error_log('Python script failed: ' . implode("\n", $output));
|
||||
}
|
||||
```
|
||||
|
||||
`/var/www/scripts/` のようなPVC上の非公開フォルダにPythonスクリプトを配置すれば、Web経由で公開されずに済みます(詳細はPVCマウント構成の項を参照)。
|
||||
|
||||
**デプロイ手順**:
|
||||
|
||||
```bash
|
||||
@@ -794,6 +867,24 @@ composer:
|
||||
- "autoconf"
|
||||
```
|
||||
|
||||
### php-fpm が CrashLoopBackOff/全リクエストが 502(`Address in use` / `unsupported FastCGI protocol version: 60`)
|
||||
|
||||
**症状**: php-fpm コンテナが `CrashLoopBackOff` になり、nginx ログに `upstream sent unsupported FastCGI protocol version: 60`、php-fpm ログに次が出る。
|
||||
|
||||
```
|
||||
[ERROR] unable to bind listening socket for address '9000': Address in use (98)
|
||||
[ERROR] FPM initialization failed
|
||||
```
|
||||
|
||||
**原因**: php-fpm が 9000 を bind できず起動失敗し、nginx が非 FastCGI 応答を受けて 502 になる。v8.5.9-c 以前は php-fpm を setup シェルの子プロセスとして起動していたため、コンテナ再起動時に PID1 のシェルが `SIGTERM` を子へ転送せず、旧 php-fpm が残存して 9000 を握ったまま次回起動が二重 bind で失敗する自己増殖ループに陥ることがあった。
|
||||
|
||||
**対策**: **v8.5.9-d 以降にアップグレードする**(起動を `exec php-fpm -F` に変更済み。php-fpm が PID1 になりシグナルを直接受けて 9000 を確実解放、`-F` で必ずフォアグラウンド起動)。アップグレード後も残存プロセスを持つ既存 pod が残る場合は作り直す。
|
||||
|
||||
```bash
|
||||
helm upgrade <リリース名> cafepieters/phpfpm --version 8.5.9-d -f values.yaml
|
||||
kubectl delete pod -n <namespace> -l app.kubernetes.io/name=phpfpm
|
||||
```
|
||||
|
||||
### データベース接続エラー
|
||||
|
||||
**確認**:
|
||||
|
||||
@@ -55,6 +55,18 @@ data:
|
||||
root /var/www/html;
|
||||
index index.php index.html index.htm;
|
||||
|
||||
# アップロード可能な最大サイズ(PHP側のupload_max_filesize/post_max_sizeと連動)
|
||||
client_max_body_size {{ .Values.uploadMaxSize }};
|
||||
|
||||
# sitemap.xml のContent-Typeを明示的に指定
|
||||
# 標準のmime.typesでは .xml は text/xml 扱いでcharsetが付かず、
|
||||
# ブラウザやSearch Consoleが正しく解釈できない場合があるため
|
||||
location = /sitemap.xml {
|
||||
types { }
|
||||
default_type "application/xml; charset=utf-8";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,15 @@ spec:
|
||||
- |
|
||||
echo "Starting PHP-FPM setup process..."
|
||||
|
||||
{{- if or .Values.composer.enabled .Values.selenium.enabled .Values.externalDatabase.enabled }}
|
||||
# ========================================
|
||||
# アップロードサイズ上限(nginxのclient_max_body_sizeと連動)
|
||||
# ========================================
|
||||
cat > /usr/local/etc/php/conf.d/99-uploads.ini << 'UPLOADS_INI_EOF'
|
||||
upload_max_filesize = {{ .Values.uploadMaxSize }}
|
||||
post_max_size = {{ .Values.uploadMaxSize }}
|
||||
UPLOADS_INI_EOF
|
||||
|
||||
{{- if or .Values.composer.enabled .Values.selenium.enabled .Values.externalDatabase.enabled .Values.python.enabled }}
|
||||
# ========================================
|
||||
# APKパッケージのインストール
|
||||
# ========================================
|
||||
@@ -57,13 +65,25 @@ spec:
|
||||
APK_PACKAGES="$APK_PACKAGES msmtp ca-certificates"
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.python.enabled }}
|
||||
# Python本体に必要なパッケージ
|
||||
APK_PACKAGES="$APK_PACKAGES python3 py3-pip"
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.composer.additionalApkPackages }}
|
||||
# ユーザー指定の追加APKパッケージ
|
||||
# ユーザー指定の追加APKパッケージ(Composer用)
|
||||
{{- range .Values.composer.additionalApkPackages }}
|
||||
APK_PACKAGES="$APK_PACKAGES {{ . }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.python.additionalApkPackages }}
|
||||
# ユーザー指定の追加APKパッケージ(Python用)
|
||||
{{- range .Values.python.additionalApkPackages }}
|
||||
APK_PACKAGES="$APK_PACKAGES {{ . }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
# PHP拡張(gd / mbstring)の依存パッケージを自動的に追加
|
||||
{{- if .Values.composer.additionalPhpExtensions }}
|
||||
for ext in {{ join " " .Values.composer.additionalPhpExtensions }}; do
|
||||
@@ -172,6 +192,38 @@ spec:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.python.enabled }}
|
||||
{{- $pythonDir := .Values.python.venvDir | default "/venv" }}
|
||||
# ========================================
|
||||
# Python仮想環境のセットアップ
|
||||
# ========================================
|
||||
echo "Setting up Python virtual environment..."
|
||||
|
||||
# Python導入先(デフォルトはWebルート外の /venv、Composerと同様の使い捨て領域)
|
||||
# PHPからの呼び出し方: exec('{{ $pythonDir }}/bin/python3 /path/to/script.py 2>&1', $output, $exitCode);
|
||||
python3 -m venv {{ $pythonDir }}
|
||||
|
||||
{{- if .Values.python.useRequirementsTxt }}
|
||||
echo "Creating requirements.txt from values..."
|
||||
cat > /tmp/requirements.txt << 'REQUIREMENTS_TXT_EOF'
|
||||
{{- .Values.python.requirementsTxt | trim | nindent 14 }}
|
||||
REQUIREMENTS_TXT_EOF
|
||||
|
||||
echo "Installing Python packages from requirements.txt..."
|
||||
{{ $pythonDir }}/bin/pip install {{ .Values.python.installOptions }} -r /tmp/requirements.txt
|
||||
rm -f /tmp/requirements.txt
|
||||
|
||||
{{- else if .Values.python.packages }}
|
||||
echo "Installing Python packages..."
|
||||
{{- range .Values.python.packages }}
|
||||
{{ $pythonDir }}/bin/pip install {{ $.Values.python.installOptions }} "{{ . }}"
|
||||
{{- end }}
|
||||
|
||||
{{- else }}
|
||||
echo "No Python package configuration found, virtual environment created without additional packages"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.smtp.enabled }}
|
||||
# ========================================
|
||||
# SMTP設定(msmtp)
|
||||
@@ -200,7 +252,16 @@ spec:
|
||||
{{- end }}
|
||||
|
||||
echo "Setup complete, starting PHP-FPM..."
|
||||
php-fpm
|
||||
# exec で php-fpm をコンテナの PID1 に置き換える。
|
||||
# 目的: setup シェルを介さず php-fpm 自身が SIGTERM/SIGKILL を直接受け取れる
|
||||
# ようにする。シェルは既定で子プロセスへシグナルを転送しないため、exec せず
|
||||
# `php-fpm`(子)のまま起動すると、コンテナ再起動時にシェル(PID1)だけが落ちて
|
||||
# 旧 php-fpm が一時的に残存し、9000 を握ったまま次回起動が
|
||||
# 「unable to bind ... '9000': Address in use」で失敗して CrashLoopBackOff に陥る。
|
||||
# exec すれば php-fpm が PID1 になり、停止時に 9000 が確実に解放される。
|
||||
# -F(--nodaemonize): 設定に依存せず必ずフォアグラウンドで起動する
|
||||
# (デーモン化して master が背後に残る事故を防ぐ)。
|
||||
exec php-fpm -F
|
||||
ports:
|
||||
- containerPort: 9000 # PHP-FPMは9000ポートでリッスン
|
||||
volumeMounts:
|
||||
|
||||
@@ -6,7 +6,9 @@ metadata:
|
||||
labels:
|
||||
{{- include "phpfpm.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
{{- toYaml .Values.ingress.annotations | nindent 4 }}
|
||||
{{- /* uploadMaxSize を ingress-nginx の proxy-body-size に自動反映(明示指定があればそちらを優先) */}}
|
||||
{{- $ingressAnnotations := merge (deepCopy .Values.ingress.annotations) (dict "nginx.ingress.kubernetes.io/proxy-body-size" .Values.uploadMaxSize) }}
|
||||
{{- toYaml $ingressAnnotations | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
|
||||
+53
-5
@@ -4,17 +4,17 @@ image:
|
||||
nginx:
|
||||
registry: docker.io
|
||||
repository: nginx
|
||||
tag: "1.31.3-alpine-perl"
|
||||
tag: "1.31.5-alpine-perl"
|
||||
pullPolicy: IfNotPresent
|
||||
php:
|
||||
registry: docker.io
|
||||
repository: php
|
||||
tag: "8.5.8-fpm-alpine3.24"
|
||||
tag: "8.5.10-fpm-alpine3.24"
|
||||
pullPolicy: IfNotPresent
|
||||
selenium:
|
||||
registry: docker.io
|
||||
repository: selenium/standalone-chromium
|
||||
tag: "150.0-chromedriver-150.0"
|
||||
tag: "152.0-chromedriver-152.0"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
service:
|
||||
@@ -22,15 +22,25 @@ service:
|
||||
type: LoadBalancer
|
||||
port: 80
|
||||
|
||||
# アップロード可能な最大サイズ
|
||||
# 以下3箇所に同じ値を反映する(どれか一つでも小さいと、そこで上限に達して失敗するため):
|
||||
# - nginx(Podコンテナ内)の client_max_body_size
|
||||
# - PHPの upload_max_filesize / post_max_size
|
||||
# - ingress.enabled: true の場合、ingress-nginxの nginx.ingress.kubernetes.io/proxy-body-size
|
||||
# 単位はnginx/PHP共通でk/m/g(大文字小文字問わず)が使用可能(例: "100m", "1g")
|
||||
uploadMaxSize: "100m"
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
# nginx.ingress.kubernetes.io/proxy-body-size は uploadMaxSize の値が自動的に付与されるため
|
||||
# 明示的に指定する必要はない(Ingress側の上限もnginx/PHPと揃う)
|
||||
# 別の値にしたい場合や別コントローラーを使う場合は、ここに明示指定すれば上書きされる
|
||||
annotations: {}
|
||||
# {
|
||||
# acme.cert-manager.io/http01-ingress-class: "nginx",
|
||||
# cert-manager.io/cluster-issuer: "letsencrypt-issuer",
|
||||
# nginx.ingress.kubernetes.io/from-to-www-redirect: "true",
|
||||
# nginx.ingress.kubernetes.io/proxy-body-size: "100m"
|
||||
# nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
|
||||
# }
|
||||
hosts:
|
||||
- host: example.tld
|
||||
@@ -131,6 +141,44 @@ composer:
|
||||
# - "gd"
|
||||
# - "zip"
|
||||
|
||||
# Python設定(オプション、PHPからPythonスクリプトを呼び出す用途)
|
||||
python:
|
||||
# Pythonを使用するかどうか
|
||||
enabled: false
|
||||
|
||||
# Python仮想環境(venv)の導入先ディレクトリ
|
||||
# デフォルトの /venv はWebルート外かつPVCにマウントされない「使い捨て」領域:
|
||||
# - Pod再起動のたびにクリーンな環境へ再構築される(Composerと同じ設計)
|
||||
#
|
||||
# 【重要】PHPからのPython呼び出し方(execを利用):
|
||||
# exec('/venv/bin/python3 /path/to/script.py 2>&1', $output, $exitCode);
|
||||
#
|
||||
# PVC上に永続化したい場合は /var/www 配下(例: "/var/www/venv")を指定
|
||||
venvDir: "/venv"
|
||||
|
||||
# pipでインストールするパッケージ
|
||||
# packages配列が空の場合、requirements.txtを使用
|
||||
packages: []
|
||||
# - "requests>=2.31.0"
|
||||
# - "pillow"
|
||||
|
||||
# requirements.txtを使用する場合
|
||||
useRequirementsTxt: false
|
||||
|
||||
# requirements.txtの内容(useRequirementsTxt: trueの場合に使用)
|
||||
requirementsTxt: |
|
||||
requests>=2.31.0
|
||||
|
||||
# pip installのオプション
|
||||
installOptions: "--no-cache-dir"
|
||||
|
||||
# 追加のAPKパッケージ(ネイティブ拡張のビルドに必要な場合、例: numpy等)
|
||||
additionalApkPackages: []
|
||||
# - "gcc"
|
||||
# - "musl-dev"
|
||||
# - "python3-dev"
|
||||
# - "jpeg-dev"
|
||||
|
||||
# Selenium設定(レガシー互換性維持)
|
||||
selenium:
|
||||
enabled: false
|
||||
|
||||
Reference in New Issue
Block a user