Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adc9ce5934 | ||
| ef238e9c42 | |||
| 28eb82a1d6 | |||
|
|
c31ee5ce93 | ||
| e21bc2e1a5 | |||
| 3343995e21 | |||
| a3f0245c64 | |||
| 6002da51d0 | |||
| 02696fc55e | |||
| 59a21fca9b | |||
| 31106e098f | |||
| fb6ebfe2b0 | |||
| fcd6bdbda5 | |||
| 6ab36861ab | |||
| 58c02e47a9 | |||
| 6c4f7c0bf2 | |||
|
|
3ced61563a |
@@ -48,26 +48,35 @@ jobs:
|
|||||||
echo "Checking PHP versions..."
|
echo "Checking PHP versions..."
|
||||||
CURRENT=$(grep -A3 "php:" values.yaml | grep "tag:" | head -1 | sed 's/.*tag: *"\([^"]*\)".*/\1/' | tr -d ' ')
|
CURRENT=$(grep -A3 "php:" values.yaml | grep "tag:" | head -1 | sed 's/.*tag: *"\([^"]*\)".*/\1/' | tr -d ' ')
|
||||||
echo "Current PHP: $CURRENT"
|
echo "Current PHP: $CURRENT"
|
||||||
|
|
||||||
# Docker Hub API v2を使用してタグを取得
|
# jqの確認とインストール
|
||||||
# パターン: 8.4.12-fpm-alpine3.22 形式
|
if ! command -v jq &> /dev/null; then
|
||||||
LATEST=$(curl -s "https://registry.hub.docker.com/v2/repositories/library/php/tags?page_size=100" | \
|
echo "jq not found, installing..."
|
||||||
|
sudo apt-get update -qq && sudo apt-get install -y -qq jq
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Docker Hub API v2を使用してタグを取得(fpm-alpineでフィルタ)
|
||||||
|
echo "Fetching tags from Docker Hub..."
|
||||||
|
LATEST=$(curl -s "https://registry.hub.docker.com/v2/repositories/library/php/tags?page_size=100&name=fpm-alpine" | \
|
||||||
jq -r '.results[].name' | \
|
jq -r '.results[].name' | \
|
||||||
grep -E '^[0-9]+\.[0-9]+\.[0-9]+-fpm-alpine[0-9]+\.[0-9]+$' | \
|
grep -E '^[0-9]+\.[0-9]+\.[0-9]+-fpm-alpine[0-9]+\.[0-9]{2,3}$' | \
|
||||||
sort -V | tail -1)
|
sort -V | tail -1)
|
||||||
|
|
||||||
|
echo "DEBUG: Matched LATEST=$LATEST"
|
||||||
|
|
||||||
if [ -z "$LATEST" ]; then
|
if [ -z "$LATEST" ]; then
|
||||||
echo "Warning: Could not fetch latest PHP version, using current"
|
echo "Warning: Could not fetch latest PHP version, using current"
|
||||||
LATEST="$CURRENT"
|
LATEST="$CURRENT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# PHPバージョンを抽出 (8.4.12の部分)
|
# PHPバージョンを抽出 (8.5.2の部分)
|
||||||
APP_VERSION=$(echo "$LATEST" | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+')
|
APP_VERSION=$(echo "$LATEST" | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+')
|
||||||
if [ -z "$APP_VERSION" ]; then
|
if [ -z "$APP_VERSION" ]; then
|
||||||
echo "Error: Could not extract PHP version"
|
echo "Warning: Could not extract PHP version from: $LATEST"
|
||||||
exit 1
|
echo "Using current version instead"
|
||||||
|
APP_VERSION=$(echo "$CURRENT" | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+')
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Latest PHP: $LATEST"
|
echo "Latest PHP: $LATEST"
|
||||||
echo "PHP version: $APP_VERSION"
|
echo "PHP version: $APP_VERSION"
|
||||||
echo "current=$CURRENT" >> $GITHUB_OUTPUT
|
echo "current=$CURRENT" >> $GITHUB_OUTPUT
|
||||||
@@ -107,17 +116,38 @@ jobs:
|
|||||||
PHP_LATEST="${{ steps.php.outputs.latest }}"
|
PHP_LATEST="${{ steps.php.outputs.latest }}"
|
||||||
SELENIUM_CURRENT="${{ steps.selenium.outputs.current }}"
|
SELENIUM_CURRENT="${{ steps.selenium.outputs.current }}"
|
||||||
SELENIUM_LATEST="${{ steps.selenium.outputs.latest }}"
|
SELENIUM_LATEST="${{ steps.selenium.outputs.latest }}"
|
||||||
|
|
||||||
echo "Nginx: $NGINX_CURRENT vs $NGINX_LATEST"
|
echo "Nginx: $NGINX_CURRENT vs $NGINX_LATEST"
|
||||||
echo "PHP: $PHP_CURRENT vs $PHP_LATEST"
|
echo "PHP: $PHP_CURRENT vs $PHP_LATEST"
|
||||||
echo "Selenium: $SELENIUM_CURRENT vs $SELENIUM_LATEST"
|
echo "Selenium: $SELENIUM_CURRENT vs $SELENIUM_LATEST"
|
||||||
|
|
||||||
if [ "$NGINX_CURRENT" != "$NGINX_LATEST" ] || [ "$PHP_CURRENT" != "$PHP_LATEST" ] || [ "$SELENIUM_CURRENT" != "$SELENIUM_LATEST" ]; then
|
# 更新が必要かチェック
|
||||||
echo "update_needed=true" >> $GITHUB_OUTPUT
|
UPDATE_NEEDED=false
|
||||||
|
PHP_UPDATED=false
|
||||||
|
|
||||||
|
if [ "$PHP_CURRENT" != "$PHP_LATEST" ]; then
|
||||||
|
UPDATE_NEEDED=true
|
||||||
|
PHP_UPDATED=true
|
||||||
|
echo "PHP update detected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$NGINX_CURRENT" != "$NGINX_LATEST" ]; then
|
||||||
|
UPDATE_NEEDED=true
|
||||||
|
echo "Nginx update detected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$SELENIUM_CURRENT" != "$SELENIUM_LATEST" ]; then
|
||||||
|
UPDATE_NEEDED=true
|
||||||
|
echo "Selenium update detected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "update_needed=$UPDATE_NEEDED" >> $GITHUB_OUTPUT
|
||||||
|
echo "php_updated=$PHP_UPDATED" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
if [ "$UPDATE_NEEDED" = "true" ]; then
|
||||||
echo "Update is needed"
|
echo "Update is needed"
|
||||||
else
|
else
|
||||||
echo "update_needed=false" >> $GITHUB_OUTPUT
|
echo "Already up to date - no action required"
|
||||||
echo "Already up to date"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Update values.yaml
|
- name: Update values.yaml
|
||||||
@@ -161,7 +191,7 @@ jobs:
|
|||||||
git diff values.yaml
|
git diff values.yaml
|
||||||
|
|
||||||
- name: Update Chart.yaml version
|
- name: Update Chart.yaml version
|
||||||
if: steps.check_update.outputs.update_needed == 'true'
|
if: steps.check_update.outputs.php_updated == 'true'
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
||||||
@@ -175,26 +205,41 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
git config user.name "GitHub Actions Bot"
|
git config user.name "GitHub Actions Bot"
|
||||||
git config user.email "actions@github.com"
|
git config user.email "actions@github.com"
|
||||||
git add values.yaml Chart.yaml
|
|
||||||
git commit -m "chore: update to PHP ${{ steps.php.outputs.app_version }}, nginx ${{ steps.nginx.outputs.latest }}, selenium ${{ steps.selenium.outputs.latest }}"
|
if [ "${{ steps.check_update.outputs.php_updated }}" = "true" ]; then
|
||||||
|
# PHP更新時はChart.yamlも含める
|
||||||
|
git add values.yaml Chart.yaml
|
||||||
|
git commit -m "chore: update to PHP ${{ steps.php.outputs.app_version }}, nginx ${{ steps.nginx.outputs.latest }}, selenium ${{ steps.selenium.outputs.latest }}"
|
||||||
|
else
|
||||||
|
# Nginx/Seleniumのみの更新時はvalues.yamlのみ
|
||||||
|
git add values.yaml
|
||||||
|
git commit -m "chore: update nginx to ${{ steps.nginx.outputs.latest }}, selenium to ${{ steps.selenium.outputs.latest }} (no release)"
|
||||||
|
fi
|
||||||
|
|
||||||
git push origin main
|
git push origin main
|
||||||
|
|
||||||
- name: Package Helm Chart
|
- name: Package Helm Chart
|
||||||
if: steps.check_update.outputs.update_needed == 'true'
|
if: steps.check_update.outputs.php_updated == 'true'
|
||||||
run: |
|
run: |
|
||||||
helm package .
|
helm package .
|
||||||
echo "Helm chart packaged"
|
echo "Helm chart packaged"
|
||||||
|
|
||||||
- name: Create Git Tag
|
- name: Create Git Tag
|
||||||
if: steps.check_update.outputs.update_needed == 'true'
|
if: steps.check_update.outputs.php_updated == 'true'
|
||||||
run: |
|
run: |
|
||||||
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
||||||
git tag -a "v$APP_VERSION" -m "Release PHP $APP_VERSION"
|
|
||||||
git push origin "v$APP_VERSION"
|
# タグが既に存在する場合はスキップ
|
||||||
echo "Git tag v$APP_VERSION created"
|
if git rev-parse "v$APP_VERSION" >/dev/null 2>&1; then
|
||||||
|
echo "Tag v$APP_VERSION already exists, skipping tag creation"
|
||||||
|
else
|
||||||
|
git tag -a "v$APP_VERSION" -m "Release PHP $APP_VERSION"
|
||||||
|
git push origin "v$APP_VERSION"
|
||||||
|
echo "Git tag v$APP_VERSION created"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Create Gitea Release
|
- name: Create Gitea Release
|
||||||
if: steps.check_update.outputs.update_needed == 'true'
|
if: steps.check_update.outputs.php_updated == 'true'
|
||||||
env:
|
env:
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
@@ -202,13 +247,19 @@ jobs:
|
|||||||
CHART_NAME=$(grep '^name:' Chart.yaml | awk '{print $2}')
|
CHART_NAME=$(grep '^name:' Chart.yaml | awk '{print $2}')
|
||||||
PACKAGE_FILE="${CHART_NAME}-${APP_VERSION}.tgz"
|
PACKAGE_FILE="${CHART_NAME}-${APP_VERSION}.tgz"
|
||||||
RELEASE_BODY="PHP Helm Chart v${APP_VERSION} - Automated release"
|
RELEASE_BODY="PHP Helm Chart v${APP_VERSION} - Automated release"
|
||||||
curl -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" -d "{\"tag_name\":\"v${APP_VERSION}\",\"name\":\"v${APP_VERSION}\",\"body\":\"${RELEASE_BODY}\"}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases"
|
|
||||||
RELEASE_ID=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/tags/v${APP_VERSION}" | jq -r '.id')
|
# リリースが既に存在する場合はスキップ
|
||||||
curl -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/gzip" --data-binary "@${PACKAGE_FILE}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${PACKAGE_FILE}"
|
if curl -s -H "Authorization: token ${GITEA_TOKEN}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/tags/v${APP_VERSION}" | jq -e '.id' >/dev/null 2>&1; then
|
||||||
echo "Release created"
|
echo "Release v$APP_VERSION already exists, skipping release creation"
|
||||||
|
else
|
||||||
|
curl -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" -d "{\"tag_name\":\"v${APP_VERSION}\",\"name\":\"v${APP_VERSION}\",\"body\":\"${RELEASE_BODY}\"}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases"
|
||||||
|
RELEASE_ID=$(curl -s -H "Authorization: token ${GITEA_TOKEN}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/tags/v${APP_VERSION}" | jq -r '.id')
|
||||||
|
curl -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/gzip" --data-binary "@${PACKAGE_FILE}" "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${PACKAGE_FILE}"
|
||||||
|
echo "Release created"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Update Helm Repository Index
|
- name: Update Helm Repository Index
|
||||||
if: steps.check_update.outputs.update_needed == 'true'
|
if: steps.check_update.outputs.php_updated == 'true'
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -e
|
||||||
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
||||||
@@ -262,7 +313,16 @@ jobs:
|
|||||||
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
APP_VERSION="${{ steps.php.outputs.app_version }}"
|
||||||
NGINX_VERSION="${{ steps.nginx.outputs.latest }}"
|
NGINX_VERSION="${{ steps.nginx.outputs.latest }}"
|
||||||
SELENIUM_VERSION="${{ steps.selenium.outputs.latest }}"
|
SELENIUM_VERSION="${{ steps.selenium.outputs.latest }}"
|
||||||
|
PHP_UPDATED="${{ steps.check_update.outputs.php_updated }}"
|
||||||
|
|
||||||
echo "Update completed!"
|
echo "Update completed!"
|
||||||
echo "- PHP: ${APP_VERSION}"
|
echo "- PHP: ${APP_VERSION}"
|
||||||
echo "- Nginx: ${NGINX_VERSION}"
|
echo "- Nginx: ${NGINX_VERSION}"
|
||||||
echo "- Selenium: ${SELENIUM_VERSION}"
|
echo "- Selenium: ${SELENIUM_VERSION}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ "$PHP_UPDATED" = "true" ]; then
|
||||||
|
echo "✅ PHP version updated - Release created (v${APP_VERSION})"
|
||||||
|
else
|
||||||
|
echo "ℹ️ Nginx/Selenium only update - No release (waiting for next PHP update)"
|
||||||
|
fi
|
||||||
95
CHANGELOG-8.5.2-a.md
Normal file
95
CHANGELOG-8.5.2-a.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# Changelog - Version 8.5.2-a
|
||||||
|
|
||||||
|
## 新機能
|
||||||
|
|
||||||
|
### リアルIP転送機能の追加
|
||||||
|
|
||||||
|
ベアメタルKubernetesクラスターやLoadBalancer環境において、PHP側で訪問者の実IPアドレスを取得できる機能を追加しました。
|
||||||
|
|
||||||
|
#### 主な変更点
|
||||||
|
|
||||||
|
1. **values.yaml**
|
||||||
|
- `nginx.forwardRealIP` セクションを追加
|
||||||
|
- `enabled`: リアルIP取得機能の有効/無効
|
||||||
|
- `header`: リアルIPを取得するHTTPヘッダー名(デフォルト: X-Forwarded-For)
|
||||||
|
- `recursive`: 再帰的にリアルIPを検索(多段プロキシ対応)
|
||||||
|
- `trustedProxies`: 信頼するプロキシのネットワーク範囲
|
||||||
|
- `additionalTrustedProxies`: 環境に応じた追加プロキシ設定
|
||||||
|
|
||||||
|
2. **templates/configmap.yaml**
|
||||||
|
- Nginx の `http` セクションにリアルIP設定を追加
|
||||||
|
- `real_ip_header`, `real_ip_recursive`, `set_real_ip_from` ディレクティブを実装
|
||||||
|
- PHP-FPM へ渡す fastcgi_param にリアルIP情報を追加
|
||||||
|
- 既存の `customConfig.snippet` と競合しない構造
|
||||||
|
|
||||||
|
3. **README.md**
|
||||||
|
- リアルIP転送機能の設定パラメータ表を追加
|
||||||
|
- 例7としてベアメタル環境でのリアルIP取得の使用例を追加
|
||||||
|
- 検証用PHPコード例を追加
|
||||||
|
|
||||||
|
4. **examples/test-real-ip.php** (新規作成)
|
||||||
|
- リアルIP転送設定の動作確認用テストスクリプト
|
||||||
|
- WebUIで各種IP関連変数を確認可能
|
||||||
|
- 診断機能付き
|
||||||
|
|
||||||
|
## 技術詳細
|
||||||
|
|
||||||
|
### Nginx設定
|
||||||
|
```nginx
|
||||||
|
# HTTP-levelで設定
|
||||||
|
real_ip_header X-Forwarded-For;
|
||||||
|
real_ip_recursive on;
|
||||||
|
set_real_ip_from 10.0.0.0/8;
|
||||||
|
set_real_ip_from 172.16.0.0/12;
|
||||||
|
set_real_ip_from 192.168.0.0/16;
|
||||||
|
|
||||||
|
# PHP-FPMへ渡すパラメータ
|
||||||
|
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||||
|
fastcgi_param HTTP_X_REAL_IP $remote_addr;
|
||||||
|
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
|
||||||
|
```
|
||||||
|
|
||||||
|
### PHPでの利用
|
||||||
|
```php
|
||||||
|
// リアルIPアドレスの取得
|
||||||
|
$realIP = $_SERVER['REMOTE_ADDR'];
|
||||||
|
```
|
||||||
|
|
||||||
|
## 互換性
|
||||||
|
|
||||||
|
- 既存の `nginx.customConfig.snippet` 機能と完全に互換性あり
|
||||||
|
- デフォルトは `enabled: false` のため、既存環境への影響なし
|
||||||
|
- 有効化時のみ、リアルIP取得ロジックが動作
|
||||||
|
|
||||||
|
## セキュリティ
|
||||||
|
|
||||||
|
- `trustedProxies` には信頼できるプロキシのみを指定してください
|
||||||
|
- 不正なプロキシを信頼すると、IPスプーフィング攻撃のリスクがあります
|
||||||
|
|
||||||
|
## 使用例
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
nginx:
|
||||||
|
forwardRealIP:
|
||||||
|
enabled: true
|
||||||
|
header: "X-Forwarded-For"
|
||||||
|
recursive: true
|
||||||
|
trustedProxies:
|
||||||
|
- "10.0.0.0/8"
|
||||||
|
- "172.16.0.0/12"
|
||||||
|
- "192.168.0.0/16"
|
||||||
|
additionalTrustedProxies:
|
||||||
|
- "203.0.113.0/24" # 外部LoadBalancerのIPレンジ
|
||||||
|
```
|
||||||
|
|
||||||
|
## 検証方法
|
||||||
|
|
||||||
|
1. `examples/test-real-ip.php` を `/var/www/html/` に配置
|
||||||
|
2. ブラウザでアクセス: `http://your-service/test-real-ip.php`
|
||||||
|
3. `REMOTE_ADDR` にパブリックIPが表示されることを確認
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**リリース日**: 2026-02-10
|
||||||
|
**担当**: プロサーバーエンジニア(Claude)
|
||||||
@@ -2,6 +2,6 @@ apiVersion: v2
|
|||||||
name: phpfpm
|
name: phpfpm
|
||||||
description: Nginx + PHP-FPM Helm Chart with external DB and optional Selenium support
|
description: Nginx + PHP-FPM Helm Chart with external DB and optional Selenium support
|
||||||
type: application
|
type: application
|
||||||
version: 8.5.2
|
version: 8.5.3
|
||||||
appVersion: "8.5.2"
|
appVersion: "8.5.3"
|
||||||
icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png
|
icon: https://upload.wikimedia.org/wikipedia/commons/thumb/2/27/PHP-logo.svg/330px-PHP-logo.svg.png
|
||||||
|
|||||||
833
README.md
833
README.md
@@ -1,3 +1,832 @@
|
|||||||
# phpfpm
|
# PHP-FPM Helm Chart
|
||||||
|
|
||||||
Nginx + PHP-FPM Helm chart with external DB and optional Selenium support
|
Alpine LinuxベースのNginx + PHP-FPM環境をKubernetesにデプロイするためのHelmチャートです。Composer、Selenium、外部データベース接続など、本格的なPHPアプリケーション実行に必要な機能を統合しています。
|
||||||
|
|
||||||
|
## 特徴
|
||||||
|
|
||||||
|
- 🚀 **軽量**: Alpine Linuxベースで高速起動
|
||||||
|
- 📦 **Composer対応**: 依存パッケージ管理を柔軟にカスタマイズ
|
||||||
|
- 🌐 **Nginx統合**: PHP-FPMとNginxのマルチコンテナ構成
|
||||||
|
- 🔧 **カスタマイズ可能**: Nginx設定、PHP拡張を自由に追加
|
||||||
|
- 🤖 **Selenium統合**: ブラウザ自動化・スクレイピングに対応
|
||||||
|
- 💾 **永続化ストレージ**: PVCによるデータ永続化
|
||||||
|
- 🔐 **外部DB接続**: MySQL/MariaDB接続機能を内蔵
|
||||||
|
- 📊 **本番対応**: Ingress、TLS、リソース管理に対応
|
||||||
|
|
||||||
|
## クイックスタート
|
||||||
|
|
||||||
|
### 前提条件
|
||||||
|
|
||||||
|
- Kubernetes 1.19+
|
||||||
|
- Helm 3.0+
|
||||||
|
- PV プロビジョナー(persistence有効時)
|
||||||
|
|
||||||
|
### 基本インストール
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Helmリポジトリを追加
|
||||||
|
helm repo add cafepieters https://git.cafepieters.com/api/packages/helmchart/helm
|
||||||
|
helm repo update
|
||||||
|
|
||||||
|
# デフォルト設定でインストール
|
||||||
|
helm install my-phpfpm cafepieters/phpfpm
|
||||||
|
|
||||||
|
# カスタム設定でインストール
|
||||||
|
helm install my-phpfpm cafepieters/phpfpm -f my-values.yaml
|
||||||
|
|
||||||
|
# 特定のバージョンをインストール
|
||||||
|
helm install my-phpfpm cafepieters/phpfpm --version 2.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### ソースからのインストール
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# リポジトリのクローン
|
||||||
|
git clone https://git.cafepieters.com/helmchart/phpfpm.git
|
||||||
|
cd phpfpm
|
||||||
|
|
||||||
|
# デフォルト設定でインストール
|
||||||
|
helm install my-phpfpm .
|
||||||
|
|
||||||
|
# カスタム設定でインストール
|
||||||
|
helm install my-phpfpm . -f my-values.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 動作確認
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Podの確認
|
||||||
|
kubectl get pods -l app.kubernetes.io/name=phpfpm
|
||||||
|
|
||||||
|
# サービスの確認
|
||||||
|
kubectl get svc -l app.kubernetes.io/name=phpfpm
|
||||||
|
|
||||||
|
# ログ確認
|
||||||
|
kubectl logs -l app.kubernetes.io/name=phpfpm -c php-fpm
|
||||||
|
kubectl logs -l app.kubernetes.io/name=phpfpm -c nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
## アーキテクチャ
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ Kubernetes Pod │
|
||||||
|
│ │
|
||||||
|
│ ┌──────────────┐ ┌─────────────────┐ │
|
||||||
|
│ │ Nginx │─────▶│ PHP-FPM │ │
|
||||||
|
│ │ :80 │ │ :9000 │ │
|
||||||
|
│ └──────────────┘ │ + Composer │ │
|
||||||
|
│ │ │ + Extensions │ │
|
||||||
|
│ │ └─────────────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ┌──────▼──────────────────────▼────────┐ │
|
||||||
|
│ │ Persistent Volume (PVC) │ │
|
||||||
|
│ │ /var/www/html │ │
|
||||||
|
│ └──────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────┐ │
|
||||||
|
│ │ Selenium (Optional) │ │
|
||||||
|
│ │ :4444 │ │
|
||||||
|
│ └─────────────────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ External Database (Optional) │
|
||||||
|
│ MySQL/MariaDB │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## 主要な設定パラメータ
|
||||||
|
|
||||||
|
### 基本設定
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `replicaCount` | Podのレプリカ数 | `1` |
|
||||||
|
| `image.php.tag` | PHPバージョン | `8.5.2-fpm-alpine3.23` |
|
||||||
|
| `image.nginx.tag` | Nginxバージョン | `1.29.4-alpine-perl` |
|
||||||
|
| `service.type` | Serviceタイプ | `LoadBalancer` |
|
||||||
|
| `service.port` | Serviceポート | `80` |
|
||||||
|
|
||||||
|
### 永続化ストレージ
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `persistence.enabled` | PVC有効化 | `true` |
|
||||||
|
| `persistence.size` | ストレージサイズ | `1Gi` |
|
||||||
|
| `persistence.accessMode` | アクセスモード | `ReadWriteOnce` |
|
||||||
|
|
||||||
|
### Composer設定
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `composer.enabled` | Composer有効化 | `false` |
|
||||||
|
| `composer.packages` | インストールパッケージ | `[]` |
|
||||||
|
| `composer.useComposerJson` | composer.json使用 | `false` |
|
||||||
|
| `composer.composerJson` | composer.json内容 | `""` |
|
||||||
|
| `composer.installOptions` | installオプション | `"--no-dev --optimize-autoloader"` |
|
||||||
|
| `composer.additionalPhpExtensions` | 追加PHP拡張 | `[]` |
|
||||||
|
| `composer.additionalApkPackages` | 追加APKパッケージ | `[]` |
|
||||||
|
|
||||||
|
### Selenium設定
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `selenium.enabled` | Selenium有効化 | `false` |
|
||||||
|
| `image.selenium.tag` | Seleniumバージョン | `144.0-chromedriver-144.0` |
|
||||||
|
|
||||||
|
### 外部データベース設定
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `externalDatabase.enabled` | 外部DB接続有効化 | `false` |
|
||||||
|
| `externalDatabase.host` | DBホスト名 | `mariadb-hostname` |
|
||||||
|
| `externalDatabase.port` | DBポート | `3306` |
|
||||||
|
| `externalDatabase.database` | データベース名 | `dbname` |
|
||||||
|
| `externalDatabase.username` | ユーザー名 | `user` |
|
||||||
|
| `externalDatabase.password` | パスワード | `pass` |
|
||||||
|
|
||||||
|
### Ingress設定
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `ingress.enabled` | Ingress有効化 | `false` |
|
||||||
|
| `ingress.className` | IngressClass名 | `""` |
|
||||||
|
| `ingress.annotations` | アノテーション | `{}` |
|
||||||
|
| `ingress.hosts` | ホスト設定 | `[{host: "example.tld"}]` |
|
||||||
|
| `ingress.tls` | TLS設定 | `[]` |
|
||||||
|
|
||||||
|
### Nginx設定
|
||||||
|
|
||||||
|
| パラメータ | 説明 | デフォルト |
|
||||||
|
|-----------|------|-----------|
|
||||||
|
| `nginx.customConfig.enabled` | カスタム設定有効化 | `false` |
|
||||||
|
| `nginx.customConfig.snippet` | 設定スニペット | `""` |
|
||||||
|
| `nginx.forwardRealIP.enabled` | リアルIP取得有効化 | `false` |
|
||||||
|
| `nginx.forwardRealIP.header` | リアルIP取得ヘッダー | `"X-Forwarded-For"` |
|
||||||
|
| `nginx.forwardRealIP.recursive` | 再帰的IP検索 | `true` |
|
||||||
|
| `nginx.forwardRealIP.trustedProxies` | 信頼するプロキシネットワーク | `["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]` |
|
||||||
|
| `nginx.forwardRealIP.additionalTrustedProxies` | 追加の信頼プロキシ | `[]` |
|
||||||
|
|
||||||
|
## 使用例
|
||||||
|
|
||||||
|
### 例1: シンプルなPHPアプリケーション
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
replicaCount: 2
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 5Gi
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: LoadBalancer
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "256Mi"
|
||||||
|
cpu: "200m"
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm install my-app cafepieters/phpfpm -f values.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 例2: Composerパッケージ利用
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
composer:
|
||||||
|
enabled: true
|
||||||
|
packages:
|
||||||
|
- "monolog/monolog:^3.0"
|
||||||
|
- "guzzlehttp/guzzle:^7.0"
|
||||||
|
- "vlucas/phpdotenv:^5.0"
|
||||||
|
installOptions: "--no-dev --optimize-autoloader"
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 2Gi
|
||||||
|
```
|
||||||
|
|
||||||
|
### 例3: composer.jsonを使用
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
composer:
|
||||||
|
enabled: true
|
||||||
|
useComposerJson: true
|
||||||
|
composerJson: |
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.0",
|
||||||
|
"slim/slim": "^4.0",
|
||||||
|
"slim/psr7": "^1.0",
|
||||||
|
"monolog/monolog": "^3.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "src/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
installOptions: "--optimize-autoloader"
|
||||||
|
|
||||||
|
replicaCount: 3
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: nginx
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
hosts:
|
||||||
|
- host: api.example.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: api-tls
|
||||||
|
hosts:
|
||||||
|
- api.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### 例4: MySQL接続
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
composer:
|
||||||
|
enabled: true
|
||||||
|
packages:
|
||||||
|
- "illuminate/database:^10.0"
|
||||||
|
|
||||||
|
externalDatabase:
|
||||||
|
enabled: true
|
||||||
|
host: mysql.default.svc.cluster.local
|
||||||
|
port: 3306
|
||||||
|
database: myapp
|
||||||
|
username: appuser
|
||||||
|
password: "SecurePassword123"
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 3Gi
|
||||||
|
```
|
||||||
|
|
||||||
|
### 例5: Selenium統合(スクレイピング)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
composer:
|
||||||
|
enabled: true
|
||||||
|
packages:
|
||||||
|
- "symfony/dom-crawler:^6.0"
|
||||||
|
- "symfony/css-selector:^6.0"
|
||||||
|
- "monolog/monolog:^3.0"
|
||||||
|
|
||||||
|
selenium:
|
||||||
|
enabled: true # php-webdriver/webdriverが自動追加
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 5Gi
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "1Gi"
|
||||||
|
cpu: "1000m"
|
||||||
|
limits:
|
||||||
|
memory: "3Gi"
|
||||||
|
cpu: "2000m"
|
||||||
|
```
|
||||||
|
|
||||||
|
**PHPコード例**:
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
require_once '/var/www/html/vendor/autoload.php';
|
||||||
|
|
||||||
|
use Facebook\WebDriver\Remote\RemoteWebDriver;
|
||||||
|
use Facebook\WebDriver\Remote\DesiredCapabilities;
|
||||||
|
|
||||||
|
// Seleniumに接続
|
||||||
|
$driver = RemoteWebDriver::create(
|
||||||
|
'http://localhost:4444',
|
||||||
|
DesiredCapabilities::chrome()
|
||||||
|
);
|
||||||
|
|
||||||
|
$driver->get('https://example.com');
|
||||||
|
echo $driver->getTitle();
|
||||||
|
$driver->quit();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 例6: カスタムNginx設定
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
nginx:
|
||||||
|
customConfig:
|
||||||
|
enabled: true
|
||||||
|
snippet: |
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
|
||||||
|
fastcgi_read_timeout 300;
|
||||||
|
fastcgi_send_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /admin {
|
||||||
|
auth_basic "Administrator Area";
|
||||||
|
auth_basic_user_file /etc/nginx/.htpasswd;
|
||||||
|
}
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### 例7: ベアメタル環境でのリアルIP取得
|
||||||
|
|
||||||
|
ベアメタルKubernetesやLoadBalancer経由でのアクセスで、PHPからクライアントの実IPアドレスを取得する設定です。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
service:
|
||||||
|
type: LoadBalancer
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
forwardRealIP:
|
||||||
|
# リアルIP取得機能を有効化
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# リアルIPを取得するヘッダー(環境に応じて変更)
|
||||||
|
# - X-Real-IP: シンプルな1段プロキシ
|
||||||
|
# - X-Forwarded-For: 多段プロキシ対応(推奨)
|
||||||
|
header: "X-Forwarded-For"
|
||||||
|
|
||||||
|
# 再帰的にリアルIPを検索(多段プロキシ環境で推奨)
|
||||||
|
recursive: true
|
||||||
|
|
||||||
|
# 信頼するプロキシのネットワーク範囲
|
||||||
|
# ベアメタルクラスターのPodネットワークとServiceネットワークを指定
|
||||||
|
trustedProxies:
|
||||||
|
- "10.0.0.0/8" # Kubernetesデフォルトのクラスタネットワーク
|
||||||
|
- "172.16.0.0/12" # Dockerデフォルトネットワーク
|
||||||
|
- "192.168.0.0/16" # プライベートネットワーク
|
||||||
|
|
||||||
|
# 追加で信頼するプロキシ(外部LoadBalancerなど)
|
||||||
|
additionalTrustedProxies:
|
||||||
|
- "203.0.113.0/24" # 外部LoadBalancerのIPレンジ(例)
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
この設定により、PHP側で以下の変数から実IPアドレスが取得できます:
|
||||||
|
- `$_SERVER['REMOTE_ADDR']` - クライアントの実IPアドレス
|
||||||
|
- `$_SERVER['HTTP_X_REAL_IP']` - 同上(互換性用)
|
||||||
|
- `$_SERVER['HTTP_X_FORWARDED_FOR']` - プロキシチェーン全体
|
||||||
|
|
||||||
|
**検証用PHPコード:**
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
echo "Real IP: " . $_SERVER['REMOTE_ADDR'] . "\n";
|
||||||
|
echo "X-Real-IP: " . ($_SERVER['HTTP_X_REAL_IP'] ?? 'not set') . "\n";
|
||||||
|
echo "X-Forwarded-For: " . ($_SERVER['HTTP_X_FORWARDED_FOR'] ?? 'not set') . "\n";
|
||||||
|
```
|
||||||
|
|
||||||
|
**注意事項:**
|
||||||
|
- `trustedProxies`には、信頼できるプロキシ(LoadBalancer、Ingressコントローラー)のみを指定してください
|
||||||
|
- 不正なプロキシを信頼すると、IPスプーフィング攻撃のリスクがあります
|
||||||
|
- `customConfig.snippet`との併用も可能です(競合しません)
|
||||||
|
|
||||||
|
### 例8: 画像処理アプリケーション(GD拡張)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# values.yaml
|
||||||
|
composer:
|
||||||
|
enabled: true
|
||||||
|
packages:
|
||||||
|
- "intervention/image:^2.0"
|
||||||
|
additionalPhpExtensions:
|
||||||
|
- "gd"
|
||||||
|
- "exif"
|
||||||
|
additionalApkPackages:
|
||||||
|
- "libpng-dev"
|
||||||
|
- "libjpeg-turbo-dev"
|
||||||
|
- "freetype-dev"
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 10Gi
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
annotations:
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||||
|
hosts:
|
||||||
|
- host: images.example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
### 例9: 本番環境構成(フル機能)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# production-values.yaml
|
||||||
|
replicaCount: 5
|
||||||
|
|
||||||
|
image:
|
||||||
|
php:
|
||||||
|
tag: "8.5.2-fpm-alpine3.23"
|
||||||
|
nginx:
|
||||||
|
tag: "1.29.4-alpine-perl"
|
||||||
|
|
||||||
|
composer:
|
||||||
|
enabled: true
|
||||||
|
useComposerJson: true
|
||||||
|
composerJson: |
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"php": ">=8.1",
|
||||||
|
"slim/slim": "^4.0",
|
||||||
|
"monolog/monolog": "^3.0",
|
||||||
|
"vlucas/phpdotenv": "^5.0",
|
||||||
|
"firebase/php-jwt": "^6.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "src/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
installOptions: "--no-dev --optimize-autoloader --classmap-authoritative"
|
||||||
|
additionalPhpExtensions:
|
||||||
|
- "opcache"
|
||||||
|
|
||||||
|
externalDatabase:
|
||||||
|
enabled: true
|
||||||
|
host: mysql-primary.database.svc.cluster.local
|
||||||
|
port: 3306
|
||||||
|
database: production_db
|
||||||
|
username: prod_user
|
||||||
|
password: "{{ .Values.dbPassword }}" # 外部から注入
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
enabled: true
|
||||||
|
size: 20Gi
|
||||||
|
storageClass: ssd-storage
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 80
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: nginx
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
|
nginx.ingress.kubernetes.io/rate-limit: "100"
|
||||||
|
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
|
hosts:
|
||||||
|
- host: api.production.com
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: production-tls
|
||||||
|
hosts:
|
||||||
|
- api.production.com
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
customConfig:
|
||||||
|
enabled: true
|
||||||
|
snippet: |
|
||||||
|
client_max_body_size 50M;
|
||||||
|
fastcgi_read_timeout 300;
|
||||||
|
|
||||||
|
# Opcache設定
|
||||||
|
fastcgi_param PHP_VALUE "
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.memory_consumption=256
|
||||||
|
opcache.interned_strings_buffer=16
|
||||||
|
opcache.max_accelerated_files=10000
|
||||||
|
opcache.revalidate_freq=0
|
||||||
|
opcache.validate_timestamps=0
|
||||||
|
";
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "500m"
|
||||||
|
limits:
|
||||||
|
memory: "1Gi"
|
||||||
|
cpu: "1000m"
|
||||||
|
```
|
||||||
|
|
||||||
|
**デプロイ**:
|
||||||
|
```bash
|
||||||
|
# Secretを先に作成
|
||||||
|
kubectl create secret generic db-password --from-literal=password='SuperSecurePass'
|
||||||
|
|
||||||
|
# Helmリポジトリからデプロイ
|
||||||
|
helm install production-api cafepieters/phpfpm \
|
||||||
|
-f production-values.yaml \
|
||||||
|
--set externalDatabase.password=$(kubectl get secret db-password -o jsonpath='{.data.password}' | base64 -d)
|
||||||
|
```
|
||||||
|
|
||||||
|
## アップグレード
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# リポジトリを更新
|
||||||
|
helm repo update cafepieters
|
||||||
|
|
||||||
|
# 最新バージョンにアップグレード
|
||||||
|
helm upgrade my-phpfpm cafepieters/phpfpm -f values.yaml
|
||||||
|
|
||||||
|
# 特定のパラメータのみ変更
|
||||||
|
helm upgrade my-phpfpm cafepieters/phpfpm --set replicaCount=5
|
||||||
|
|
||||||
|
# 特定のバージョンにアップグレード
|
||||||
|
helm upgrade my-phpfpm cafepieters/phpfpm --version 2.1.0
|
||||||
|
|
||||||
|
# ロールバック
|
||||||
|
helm rollback my-phpfpm 1
|
||||||
|
```
|
||||||
|
|
||||||
|
## アンインストール
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# チャートの削除
|
||||||
|
helm uninstall my-phpfpm
|
||||||
|
|
||||||
|
# PVCも削除する場合
|
||||||
|
kubectl delete pvc -l app.kubernetes.io/name=phpfpm
|
||||||
|
```
|
||||||
|
|
||||||
|
## トラブルシューティング
|
||||||
|
|
||||||
|
### Pod起動が遅い
|
||||||
|
|
||||||
|
**原因**: Composerパッケージのダウンロード時間
|
||||||
|
|
||||||
|
**対策**:
|
||||||
|
```yaml
|
||||||
|
composer:
|
||||||
|
installOptions: "--no-dev --optimize-autoloader --prefer-dist"
|
||||||
|
```
|
||||||
|
|
||||||
|
### メモリ不足エラー
|
||||||
|
|
||||||
|
**対策**:
|
||||||
|
```yaml
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "512Mi"
|
||||||
|
limits:
|
||||||
|
memory: "2Gi"
|
||||||
|
```
|
||||||
|
|
||||||
|
### PHP拡張エラー
|
||||||
|
|
||||||
|
**対策**: 必要なAPKパッケージを追加
|
||||||
|
```yaml
|
||||||
|
composer:
|
||||||
|
additionalApkPackages:
|
||||||
|
- "build-base"
|
||||||
|
- "autoconf"
|
||||||
|
```
|
||||||
|
|
||||||
|
### データベース接続エラー
|
||||||
|
|
||||||
|
**確認**:
|
||||||
|
```bash
|
||||||
|
# 環境変数確認
|
||||||
|
kubectl exec -it <pod-name> -c php-fpm -- env | grep DB_
|
||||||
|
|
||||||
|
# 接続テスト
|
||||||
|
kubectl exec -it <pod-name> -c php-fpm -- mysql -h $DB_HOST -u $DB_USER -p$DB_PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
### ログ確認
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# PHP-FPMログ
|
||||||
|
kubectl logs <pod-name> -c php-fpm
|
||||||
|
|
||||||
|
# Nginxログ
|
||||||
|
kubectl logs <pod-name> -c nginx
|
||||||
|
|
||||||
|
# Seleniumログ(有効時)
|
||||||
|
kubectl logs <pod-name> -c selenium
|
||||||
|
|
||||||
|
# リアルタイム監視
|
||||||
|
kubectl logs -f <pod-name> -c php-fpm
|
||||||
|
```
|
||||||
|
|
||||||
|
## 高度な設定
|
||||||
|
|
||||||
|
### カスタムイメージの使用
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
image:
|
||||||
|
php:
|
||||||
|
registry: my-registry.com
|
||||||
|
repository: custom-php-fpm
|
||||||
|
tag: "latest"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 水平オートスケーリング
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# hpa.yaml
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: phpfpm-hpa
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: my-phpfpm
|
||||||
|
minReplicas: 2
|
||||||
|
maxReplicas: 10
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 70
|
||||||
|
```
|
||||||
|
|
||||||
|
### リソース制限の推奨値
|
||||||
|
|
||||||
|
| 環境 | CPU Request | CPU Limit | Memory Request | Memory Limit |
|
||||||
|
|------|-------------|-----------|----------------|--------------|
|
||||||
|
| 開発 | 100m | 500m | 256Mi | 512Mi |
|
||||||
|
| ステージング | 200m | 1000m | 512Mi | 1Gi |
|
||||||
|
| 本番(小) | 500m | 1000m | 512Mi | 1Gi |
|
||||||
|
| 本番(大) | 1000m | 2000m | 1Gi | 2Gi |
|
||||||
|
|
||||||
|
## セキュリティ考慮事項
|
||||||
|
|
||||||
|
### データベースパスワードの管理
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Secretの作成
|
||||||
|
kubectl create secret generic db-secret \
|
||||||
|
--from-literal=password='YourSecurePassword'
|
||||||
|
|
||||||
|
# values.yamlで参照
|
||||||
|
externalDatabase:
|
||||||
|
password: "{{ .Values.dbPassword }}"
|
||||||
|
|
||||||
|
# デプロイ時に注入
|
||||||
|
helm install my-app . \
|
||||||
|
--set dbPassword=$(kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d)
|
||||||
|
```
|
||||||
|
|
||||||
|
### NetworkPolicyの適用
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# networkpolicy.yaml
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: phpfpm-netpol
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: phpfpm
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- namespaceSelector:
|
||||||
|
matchLabels:
|
||||||
|
name: ingress-nginx
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
```
|
||||||
|
|
||||||
|
## パフォーマンス最適化
|
||||||
|
|
||||||
|
### Opcacheの有効化
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
composer:
|
||||||
|
additionalPhpExtensions:
|
||||||
|
- "opcache"
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
customConfig:
|
||||||
|
enabled: true
|
||||||
|
snippet: |
|
||||||
|
fastcgi_param PHP_VALUE "
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.memory_consumption=256
|
||||||
|
opcache.interned_strings_buffer=16
|
||||||
|
opcache.max_accelerated_files=10000
|
||||||
|
opcache.revalidate_freq=60
|
||||||
|
";
|
||||||
|
```
|
||||||
|
|
||||||
|
### Composerの最適化
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
composer:
|
||||||
|
installOptions: "--no-dev --optimize-autoloader --classmap-authoritative --apcu-autoloader"
|
||||||
|
additionalPhpExtensions:
|
||||||
|
- "apcu"
|
||||||
|
additionalApkPackages:
|
||||||
|
- "apcu-dev"
|
||||||
|
```
|
||||||
|
|
||||||
|
## よくある質問(FAQ)
|
||||||
|
|
||||||
|
**Q: Helmリポジトリを追加するには?**
|
||||||
|
|
||||||
|
A: 以下のコマンドでリポジトリを追加できます。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm repo add cafepieters https://git.cafepieters.com/api/packages/helmchart/helm
|
||||||
|
helm repo update
|
||||||
|
|
||||||
|
# 利用可能なバージョンを確認
|
||||||
|
helm search repo cafepieters/phpfpm --versions
|
||||||
|
```
|
||||||
|
|
||||||
|
**Q: PHPバージョンを変更するには?**
|
||||||
|
|
||||||
|
A: `image.php.tag`を変更してください。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
image:
|
||||||
|
php:
|
||||||
|
tag: "8.3.15-fpm-alpine3.21"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Q: 複数ドメインに対応できますか?**
|
||||||
|
|
||||||
|
A: Ingressで複数ホストを設定できます。
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
ingress:
|
||||||
|
hosts:
|
||||||
|
- host: domain1.com
|
||||||
|
paths: [...]
|
||||||
|
- host: domain2.com
|
||||||
|
paths: [...]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Q: SeleniumとComposerは同時に使えますか?**
|
||||||
|
|
||||||
|
A: はい、完全に共存可能です。
|
||||||
|
|
||||||
|
**Q: 既存のPHPアプリをデプロイするには?**
|
||||||
|
|
||||||
|
A: PVCにファイルをコピーしてください。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl cp ./my-app <pod-name>:/var/www/html/ -c php-fpm
|
||||||
|
```
|
||||||
|
|
||||||
|
## 関連ドキュメント
|
||||||
|
|
||||||
|
- [Composer使用ガイド](./COMPOSER_GUIDE.md)
|
||||||
|
- [マイグレーションガイド](./MIGRATION_GUIDE.md)
|
||||||
|
- [Selenium別チャート化設計](./SELENIUM_SEPARATION_DESIGN.md)
|
||||||
|
|
||||||
|
## ライセンス
|
||||||
|
|
||||||
|
このHelmチャートはMITライセンスで公開されています。
|
||||||
|
|
||||||
|
## サポート
|
||||||
|
|
||||||
|
- Helmリポジトリ: https://git.cafepieters.com/api/packages/helmchart/helm
|
||||||
|
- Issue: https://git.cafepieters.com/helmchart/phpfpm/issues
|
||||||
|
- リポジトリ: https://git.cafepieters.com/helmchart/phpfpm
|
||||||
|
|
||||||
|
## 変更履歴
|
||||||
|
|
||||||
|
### v2.0.0
|
||||||
|
- Composer対応追加
|
||||||
|
- PHP拡張の柔軟な追加機能
|
||||||
|
- 統合的な依存関係管理
|
||||||
|
|
||||||
|
### v1.0.0
|
||||||
|
- 初回リリース
|
||||||
|
- Nginx + PHP-FPM基本構成
|
||||||
|
- Selenium統合
|
||||||
|
- 外部データベース対応
|
||||||
226
examples/test-real-ip.php
Normal file
226
examples/test-real-ip.php
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Real IP Test Script
|
||||||
|
*
|
||||||
|
* このスクリプトは、NginxのリアルIP転送設定が正しく動作しているかを確認します。
|
||||||
|
*
|
||||||
|
* 使用方法:
|
||||||
|
* 1. values.yamlでnginx.forwardRealIP.enabled=trueに設定
|
||||||
|
* 2. このファイルを /var/www/html/ に配置
|
||||||
|
* 3. ブラウザでアクセス: http://your-service/test-real-ip.php
|
||||||
|
*/
|
||||||
|
|
||||||
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ja">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Real IP Test</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 50px auto;
|
||||||
|
padding: 20px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
background: white;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
color: #333;
|
||||||
|
border-bottom: 3px solid #4CAF50;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
padding: 12px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
tr:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.success {
|
||||||
|
color: #4CAF50;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.warning {
|
||||||
|
color: #ff9800;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
background: #e3f2fd;
|
||||||
|
padding: 15px;
|
||||||
|
border-left: 4px solid #2196F3;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
code {
|
||||||
|
background: #f4f4f4;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>🔍 Real IP Detection Test</h1>
|
||||||
|
|
||||||
|
<div class="info">
|
||||||
|
<strong>ℹ️ 情報:</strong> このページは、NginxのリアルIP転送設定が正しく動作しているかを確認します。
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>📊 IP Address Information</h2>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>変数名</th>
|
||||||
|
<th>値</th>
|
||||||
|
<th>説明</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>REMOTE_ADDR</code></td>
|
||||||
|
<td class="success"><?php echo htmlspecialchars($_SERVER['REMOTE_ADDR'] ?? 'not set'); ?></td>
|
||||||
|
<td>クライアントの実IPアドレス(Nginx real_ip設定適用後)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>HTTP_X_REAL_IP</code></td>
|
||||||
|
<td><?php echo htmlspecialchars($_SERVER['HTTP_X_REAL_IP'] ?? 'not set'); ?></td>
|
||||||
|
<td>Nginxが設定したリアルIP(互換性用)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>HTTP_X_FORWARDED_FOR</code></td>
|
||||||
|
<td><?php echo htmlspecialchars($_SERVER['HTTP_X_FORWARDED_FOR'] ?? 'not set'); ?></td>
|
||||||
|
<td>プロキシチェーン全体(カンマ区切り)</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>HTTP_CLIENT_IP</code></td>
|
||||||
|
<td><?php echo htmlspecialchars($_SERVER['HTTP_CLIENT_IP'] ?? 'not set'); ?></td>
|
||||||
|
<td>一部のプロキシが使用</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>🔧 All HTTP Headers</h2>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Header Name</th>
|
||||||
|
<th>Value</th>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
$headers = [];
|
||||||
|
foreach ($_SERVER as $key => $value) {
|
||||||
|
if (strpos($key, 'HTTP_') === 0) {
|
||||||
|
$headerName = str_replace('_', '-', substr($key, 5));
|
||||||
|
$headers[$headerName] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ksort($headers);
|
||||||
|
|
||||||
|
foreach ($headers as $name => $value) {
|
||||||
|
echo '<tr>';
|
||||||
|
echo '<td><code>' . htmlspecialchars($name) . '</code></td>';
|
||||||
|
echo '<td>' . htmlspecialchars($value) . '</td>';
|
||||||
|
echo '</tr>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>✅ 診断結果</h2>
|
||||||
|
<div class="info">
|
||||||
|
<?php
|
||||||
|
$remoteAddr = $_SERVER['REMOTE_ADDR'] ?? '';
|
||||||
|
$xForwardedFor = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? '';
|
||||||
|
|
||||||
|
// プライベートIPかどうかをチェック
|
||||||
|
function isPrivateIP($ip) {
|
||||||
|
$privateRanges = [
|
||||||
|
'10.0.0.0|10.255.255.255',
|
||||||
|
'172.16.0.0|172.31.255.255',
|
||||||
|
'192.168.0.0|192.168.255.255',
|
||||||
|
'127.0.0.0|127.255.255.255'
|
||||||
|
];
|
||||||
|
|
||||||
|
$longIP = ip2long($ip);
|
||||||
|
foreach ($privateRanges as $range) {
|
||||||
|
list($start, $end) = explode('|', $range);
|
||||||
|
if ($longIP >= ip2long($start) && $longIP <= ip2long($end)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($remoteAddr) && !isPrivateIP($remoteAddr)) {
|
||||||
|
echo '<p class="success">✅ <strong>正常:</strong> REMOTE_ADDR にパブリックIPアドレスが設定されています。</p>';
|
||||||
|
echo '<p>リアルIP転送設定が正しく動作しています。</p>';
|
||||||
|
} elseif (!empty($remoteAddr) && isPrivateIP($remoteAddr)) {
|
||||||
|
echo '<p class="warning">⚠️ <strong>注意:</strong> REMOTE_ADDR がプライベートIPアドレスです: ' . htmlspecialchars($remoteAddr) . '</p>';
|
||||||
|
echo '<p>これは以下のいずれかが原因です:</p>';
|
||||||
|
echo '<ul>';
|
||||||
|
echo '<li>リアルIP転送設定(nginx.forwardRealIP.enabled)が無効</li>';
|
||||||
|
echo '<li>trustedProxiesの設定が不適切</li>';
|
||||||
|
echo '<li>LoadBalancerがX-Forwarded-Forヘッダーを送信していない</li>';
|
||||||
|
echo '</ul>';
|
||||||
|
|
||||||
|
if (!empty($xForwardedFor)) {
|
||||||
|
echo '<p><strong>ヒント:</strong> X-Forwarded-For ヘッダーには値があります: ' . htmlspecialchars($xForwardedFor) . '</p>';
|
||||||
|
echo '<p>values.yaml で <code>nginx.forwardRealIP.enabled: true</code> に設定してください。</p>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo '<p class="warning">⚠️ REMOTE_ADDR が設定されていません</p>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>📝 PHPでの使用例</h2>
|
||||||
|
<pre style="background: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto;">
|
||||||
|
<code><?php
|
||||||
|
/**
|
||||||
|
* 訪問者のリアルIPアドレスを取得する関数
|
||||||
|
*/
|
||||||
|
function getRealIP() {
|
||||||
|
// nginx.forwardRealIP.enabled が true の場合、
|
||||||
|
// REMOTE_ADDR に実IPが設定されている
|
||||||
|
return $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用例
|
||||||
|
$visitorIP = getRealIP();
|
||||||
|
echo "訪問者のIPアドレス: " . $visitorIP;
|
||||||
|
|
||||||
|
// データベースに記録する例
|
||||||
|
// $stmt = $pdo->prepare("INSERT INTO access_log (ip_address, visited_at) VALUES (?, NOW())");
|
||||||
|
// $stmt->execute([$visitorIP]);
|
||||||
|
?></code></pre>
|
||||||
|
|
||||||
|
<h2>⚙️ Helm設定例</h2>
|
||||||
|
<pre style="background: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto;">
|
||||||
|
<code># values.yaml
|
||||||
|
nginx:
|
||||||
|
forwardRealIP:
|
||||||
|
enabled: true
|
||||||
|
header: "X-Forwarded-For"
|
||||||
|
recursive: true
|
||||||
|
trustedProxies:
|
||||||
|
- "10.0.0.0/8"
|
||||||
|
- "172.16.0.0/12"
|
||||||
|
- "192.168.0.0/16"
|
||||||
|
additionalTrustedProxies:
|
||||||
|
- "あなたのLoadBalancerのIPレンジ"</code></pre>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
15
templates/configmap-composer.yaml
Normal file
15
templates/configmap-composer.yaml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{{- if and .Values.composer.enabled .Values.composer.useComposerJson }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "phpfpm.fullname" . }}-composer-config
|
||||||
|
labels:
|
||||||
|
{{- include "phpfpm.labels" . | nindent 4 }}
|
||||||
|
data:
|
||||||
|
composer.json: |
|
||||||
|
{{ .Values.composer.composerJson | indent 4 }}
|
||||||
|
{{- if .Values.composer.composerLock }}
|
||||||
|
composer.lock: |
|
||||||
|
{{ .Values.composer.composerLock | indent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
92
templates/configmap-nginx.yaml
Normal file
92
templates/configmap-nginx.yaml
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
{{- if .Values.nginx.enabled }}
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ include "phpfpm.fullname" . }}-nginx-config
|
||||||
|
labels:
|
||||||
|
{{- include "phpfpm.labels" . | nindent 4 }}
|
||||||
|
data:
|
||||||
|
default.conf: |
|
||||||
|
{{- if or .Values.nginx.forwardRealIP.enabled (and .Values.nginx.customConfig.enabled .Values.nginx.customConfig.httpSnippet) }}
|
||||||
|
# HTTP-level configuration
|
||||||
|
{{- if .Values.nginx.forwardRealIP.enabled }}
|
||||||
|
# Real IP forwarding configuration
|
||||||
|
real_ip_header {{ .Values.nginx.forwardRealIP.header }};
|
||||||
|
{{- if .Values.nginx.forwardRealIP.recursive }}
|
||||||
|
real_ip_recursive on;
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# Trusted proxy networks
|
||||||
|
{{- range .Values.nginx.forwardRealIP.trustedProxies }}
|
||||||
|
set_real_ip_from {{ . }};
|
||||||
|
{{- end }}
|
||||||
|
{{- range .Values.nginx.forwardRealIP.additionalTrustedProxies }}
|
||||||
|
set_real_ip_from {{ . }};
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if and .Values.nginx.customConfig.enabled .Values.nginx.customConfig.httpSnippet }}
|
||||||
|
# Custom HTTP-level configuration
|
||||||
|
{{ .Values.nginx.customConfig.httpSnippet | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
server_name _;
|
||||||
|
root /var/www/html;
|
||||||
|
index index.php index.html;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
|
||||||
|
{{- if and .Values.nginx.customConfig.enabled .Values.nginx.customConfig.serverSnippet }}
|
||||||
|
# Custom server-level configuration
|
||||||
|
{{ .Values.nginx.customConfig.serverSnippet | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default location block
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
# PHP-FPM handler
|
||||||
|
location ~ \.php$ {
|
||||||
|
try_files $uri =404;
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
|
|
||||||
|
{{- if .Values.nginx.forwardRealIP.enabled }}
|
||||||
|
# Pass real IP information to PHP-FPM
|
||||||
|
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||||
|
fastcgi_param HTTP_X_REAL_IP $realip_remote_addr;
|
||||||
|
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# Standard FastCGI parameters
|
||||||
|
fastcgi_param SERVER_NAME $host;
|
||||||
|
fastcgi_param SERVER_PORT $server_port;
|
||||||
|
fastcgi_param HTTPS $https if_not_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Deny access to hidden files
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
access_log off;
|
||||||
|
log_not_found off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
@@ -29,6 +29,25 @@ data:
|
|||||||
sendfile on;
|
sendfile on;
|
||||||
keepalive_timeout 65;
|
keepalive_timeout 65;
|
||||||
|
|
||||||
|
{{- if .Values.nginx.forwardRealIP.enabled }}
|
||||||
|
# ========================================
|
||||||
|
# Real IP forwarding configuration
|
||||||
|
# ========================================
|
||||||
|
# クライアントの実IPアドレスを取得する設定
|
||||||
|
real_ip_header {{ .Values.nginx.forwardRealIP.header }};
|
||||||
|
{{- if .Values.nginx.forwardRealIP.recursive }}
|
||||||
|
real_ip_recursive on;
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# 信頼するプロキシのネットワーク範囲
|
||||||
|
{{- range .Values.nginx.forwardRealIP.trustedProxies }}
|
||||||
|
set_real_ip_from {{ . }};
|
||||||
|
{{- end }}
|
||||||
|
{{- range .Values.nginx.forwardRealIP.additionalTrustedProxies }}
|
||||||
|
set_real_ip_from {{ . }};
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name localhost;
|
server_name localhost;
|
||||||
@@ -45,6 +64,12 @@ data:
|
|||||||
fastcgi_pass 127.0.0.1:9000;
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
{{- if .Values.nginx.forwardRealIP.enabled }}
|
||||||
|
# リアルIP情報をPHP-FPMに渡す
|
||||||
|
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||||
|
fastcgi_param HTTP_X_REAL_IP $remote_addr;
|
||||||
|
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
|
||||||
|
{{- end }}
|
||||||
}
|
}
|
||||||
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
|||||||
@@ -34,23 +34,116 @@ spec:
|
|||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
echo "Starting PHP-FPM with conditional logic..."
|
echo "Starting PHP-FPM setup process..."
|
||||||
{{- if or .Values.selenium.enabled .Values.externalDatabase.enabled }}
|
|
||||||
(
|
{{- if or .Values.composer.enabled .Values.selenium.enabled .Values.externalDatabase.enabled }}
|
||||||
{{- if .Values.selenium.enabled }}
|
# ========================================
|
||||||
echo "Installing selenium dependencies..."
|
# APKパッケージのインストール
|
||||||
apk add --no-cache curl zip libzip-dev && \
|
# ========================================
|
||||||
docker-php-ext-install zip && \
|
APK_PACKAGES=""
|
||||||
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
|
|
||||||
composer require php-webdriver/webdriver
|
{{- if or .Values.composer.enabled .Values.selenium.enabled }}
|
||||||
{{- end }}
|
# Composer本体に必要なパッケージ
|
||||||
{{- if .Values.externalDatabase.enabled }}
|
APK_PACKAGES="$APK_PACKAGES curl zip libzip-dev"
|
||||||
echo "Installing pdo_mysql for PHP 8.4 Alpine..."
|
|
||||||
apk add --no-cache mysql-client mysql-dev
|
|
||||||
docker-php-ext-install pdo_mysql
|
|
||||||
{{- end }}
|
|
||||||
)
|
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.externalDatabase.enabled }}
|
||||||
|
# MySQL/MariaDB接続に必要なパッケージ
|
||||||
|
APK_PACKAGES="$APK_PACKAGES mysql-client mysql-dev"
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.composer.additionalApkPackages }}
|
||||||
|
# ユーザー指定の追加APKパッケージ
|
||||||
|
{{- range .Values.composer.additionalApkPackages }}
|
||||||
|
APK_PACKAGES="$APK_PACKAGES {{ . }}"
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
if [ -n "$APK_PACKAGES" ]; then
|
||||||
|
echo "Installing APK packages: $APK_PACKAGES"
|
||||||
|
apk add --no-cache $APK_PACKAGES
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# PHP拡張のインストール
|
||||||
|
# ========================================
|
||||||
|
{{- if or .Values.composer.enabled .Values.selenium.enabled }}
|
||||||
|
echo "Installing PHP zip extension..."
|
||||||
|
docker-php-ext-install zip
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.externalDatabase.enabled }}
|
||||||
|
echo "Installing pdo_mysql extension..."
|
||||||
|
docker-php-ext-install pdo_mysql
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.composer.additionalPhpExtensions }}
|
||||||
|
echo "Installing additional PHP extensions..."
|
||||||
|
{{- range .Values.composer.additionalPhpExtensions }}
|
||||||
|
docker-php-ext-install {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
# ========================================
|
||||||
|
# Composerのインストールと実行
|
||||||
|
# ========================================
|
||||||
|
{{- if or .Values.composer.enabled .Values.selenium.enabled }}
|
||||||
|
echo "Installing Composer..."
|
||||||
|
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
cd /var/www/html
|
||||||
|
|
||||||
|
{{- if .Values.composer.enabled }}
|
||||||
|
# ユーザー定義のComposer設定
|
||||||
|
{{- if .Values.composer.useComposerJson }}
|
||||||
|
# composer.jsonファイルを使用
|
||||||
|
echo "Creating composer.json from values..."
|
||||||
|
cat > composer.json << 'COMPOSER_JSON_EOF'
|
||||||
|
{{ .Values.composer.composerJson }}
|
||||||
|
COMPOSER_JSON_EOF
|
||||||
|
|
||||||
|
{{- if .Values.composer.composerLock }}
|
||||||
|
echo "Creating composer.lock from values..."
|
||||||
|
cat > composer.lock << 'COMPOSER_LOCK_EOF'
|
||||||
|
{{ .Values.composer.composerLock }}
|
||||||
|
COMPOSER_LOCK_EOF
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
echo "Running composer install..."
|
||||||
|
composer install {{ .Values.composer.installOptions }}
|
||||||
|
|
||||||
|
{{- else if .Values.composer.packages }}
|
||||||
|
# パッケージリストから直接インストール
|
||||||
|
echo "Installing Composer packages..."
|
||||||
|
{{- range .Values.composer.packages }}
|
||||||
|
composer require {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.composer.installOptions }}
|
||||||
|
# オプティマイズ実行
|
||||||
|
composer install {{ .Values.composer.installOptions }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- else }}
|
||||||
|
# composer.jsonが既に存在する場合はそれを使用
|
||||||
|
if [ -f composer.json ]; then
|
||||||
|
echo "Found existing composer.json, running composer install..."
|
||||||
|
composer install {{ .Values.composer.installOptions }}
|
||||||
|
else
|
||||||
|
echo "No composer configuration found, skipping package installation"
|
||||||
|
fi
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if .Values.selenium.enabled }}
|
||||||
|
# Selenium用のパッケージインストール(レガシー互換性)
|
||||||
|
echo "Installing Selenium WebDriver package..."
|
||||||
|
composer require php-webdriver/webdriver
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
echo "Setup complete, starting PHP-FPM..."
|
||||||
php-fpm
|
php-fpm
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 9000 # PHP-FPMは9000ポートでリッスン
|
- containerPort: 9000 # PHP-FPMは9000ポートでリッスン
|
||||||
@@ -58,6 +151,10 @@ spec:
|
|||||||
- name: app-storage
|
- name: app-storage
|
||||||
mountPath: /var/www/html
|
mountPath: /var/www/html
|
||||||
subPath: html
|
subPath: html
|
||||||
|
{{- if and .Values.composer.enabled .Values.composer.useComposerJson }}
|
||||||
|
- name: composer-config
|
||||||
|
mountPath: /tmp/composer-init
|
||||||
|
{{- end }}
|
||||||
env:
|
env:
|
||||||
{{- if .Values.externalDatabase.enabled }}
|
{{- if .Values.externalDatabase.enabled }}
|
||||||
- name: DB_HOST
|
- name: DB_HOST
|
||||||
@@ -101,3 +198,8 @@ spec:
|
|||||||
- name: nginx-config
|
- name: nginx-config
|
||||||
configMap:
|
configMap:
|
||||||
name: {{ include "phpfpm.fullname" . }}-nginx-config
|
name: {{ include "phpfpm.fullname" . }}-nginx-config
|
||||||
|
{{- if and .Values.composer.enabled .Values.composer.useComposerJson }}
|
||||||
|
- name: composer-config
|
||||||
|
configMap:
|
||||||
|
name: {{ include "phpfpm.fullname" . }}-composer-config
|
||||||
|
{{- end }}
|
||||||
71
values.yaml
71
values.yaml
@@ -4,17 +4,17 @@ image:
|
|||||||
nginx:
|
nginx:
|
||||||
registry: docker.io
|
registry: docker.io
|
||||||
repository: nginx
|
repository: nginx
|
||||||
tag: "1.29.4-alpine-perl"
|
tag: "1.29.5-alpine-perl"
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
php:
|
php:
|
||||||
registry: docker.io
|
registry: docker.io
|
||||||
repository: php
|
repository: php
|
||||||
tag: "8.5.2-fpm-alpine3.22"
|
tag: "8.5.3-fpm-alpine3.23"
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
selenium:
|
selenium:
|
||||||
registry: docker.io
|
registry: docker.io
|
||||||
repository: selenium/standalone-chromium
|
repository: selenium/standalone-chromium
|
||||||
tag: "143.0-chromedriver-143.0"
|
tag: "144.0-chromedriver-144.0"
|
||||||
pullPolicy: IfNotPresent
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
service:
|
service:
|
||||||
@@ -55,7 +55,70 @@ nginx:
|
|||||||
enabled: false
|
enabled: false
|
||||||
snippet: |-
|
snippet: |-
|
||||||
|
|
||||||
|
# リアルIP転送設定(ベアメタル/LoadBalancer環境向け)
|
||||||
|
forwardRealIP:
|
||||||
|
# リアルIP取得機能を有効化
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# リアルIPを取得するヘッダー名
|
||||||
|
# LoadBalancer/Ingressによって異なる
|
||||||
|
# - X-Real-IP: シンプルな1段プロキシ
|
||||||
|
# - X-Forwarded-For: 多段プロキシ対応(推奨)
|
||||||
|
header: "X-Forwarded-For"
|
||||||
|
|
||||||
|
# 再帰的にリアルIPを検索(多段プロキシ環境で推奨)
|
||||||
|
recursive: true
|
||||||
|
|
||||||
|
# 信頼するプロキシのネットワーク範囲
|
||||||
|
# ベアメタルクラスターでは、PodネットワークとServiceネットワークを指定
|
||||||
|
trustedProxies:
|
||||||
|
- "10.0.0.0/8" # プライベートネットワーク
|
||||||
|
- "172.16.0.0/12" # プライベートネットワーク
|
||||||
|
- "192.168.0.0/16" # プライベートネットワーク
|
||||||
|
|
||||||
|
# 追加で信頼するプロキシ(環境に応じてカスタマイズ)
|
||||||
|
additionalTrustedProxies: []
|
||||||
|
# - "203.0.113.0/24" # 外部LoadBalancerなど
|
||||||
|
|
||||||
|
# Composer設定
|
||||||
|
composer:
|
||||||
|
# Composerを使用するかどうか
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# Composerでインストールするパッケージ
|
||||||
|
# packages配列が空の場合、composer.jsonを使用
|
||||||
|
packages: []
|
||||||
|
# - "monolog/monolog:^2.0"
|
||||||
|
# - "guzzlehttp/guzzle:^7.0"
|
||||||
|
|
||||||
|
# composer.jsonファイルを使用する場合
|
||||||
|
useComposerJson: false
|
||||||
|
|
||||||
|
# composer.jsonの内容(useComposerJson: trueの場合に使用)
|
||||||
|
composerJson: |
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"monolog/monolog": "^2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# composer.lockファイルの内容(オプション、再現性を保証)
|
||||||
|
composerLock: ""
|
||||||
|
|
||||||
|
# Composerのインストールオプション
|
||||||
|
installOptions: "--no-dev --optimize-autoloader"
|
||||||
|
|
||||||
|
# 追加のAPKパッケージ(Composer依存関係のビルドに必要な場合)
|
||||||
|
additionalApkPackages: []
|
||||||
|
# - "libpng-dev"
|
||||||
|
# - "libjpeg-turbo-dev"
|
||||||
|
|
||||||
|
# 追加のPHP拡張(docker-php-ext-installで導入)
|
||||||
|
additionalPhpExtensions: []
|
||||||
|
# - "gd"
|
||||||
|
# - "zip"
|
||||||
|
|
||||||
|
# Selenium設定(レガシー互換性維持)
|
||||||
selenium:
|
selenium:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
||||||
@@ -67,4 +130,4 @@ externalDatabase:
|
|||||||
username: user
|
username: user
|
||||||
password: pass
|
password: pass
|
||||||
|
|
||||||
resources: {}
|
resources: {}
|
||||||
Reference in New Issue
Block a user