# 01 サーバー構成

本システム（肌診断ASP）の現行サーバー構成を記載する。将来的に別サーバーでの再構築が発生した場合は、本章の内容と同等の環境を用意すること。

なお、本構成は、現行肌診断ASPのうち、**オフラインPDF型の継続運用を前提とした構成**であり、オンラインHTML型は今回の移行・継続運用対象外とする。

---

## 1. サーバー全体像

単一の Linux サーバー上で、以下の 3 役割を同居させている。

```
[ブラウザ]
    │  HTTPS :443 (app.hada-check.com)
    ▼
[ nginx ]  ── リバースプロキシ ──>  [ PHP Built-in Server :8000 ]
                                           （PM2 で常駐管理）
                                           │
                                           ├─> MySQL :3306 (localhost)
                                           │
                                           └─> Wine + xvfb-run で
                                               SkinDiagnosisSystem2.exe を exec()
```

| 役割 | 実体 | 備考 |
| --- | --- | --- |
| フロント Web | nginx 1.18 | HTTPS(443) で公開。80 は 443 へリダイレクト |
| アプリ Web | PHP 8.3 CLI 内蔵サーバー (`php -S localhost:8000`) | プロセス管理は PM2 |
| プロセス管理 | PM2 6.x（Node.js v20 / nvm 環境） | `skin` ユーザーで常駐 |
| 画像処理エンジン | Wine で動く `SkinDiagnosisSystem2.exe` | xvfb-run 経由で PHP から exec |
| DB | MySQL 8.0 | `localhost:3306` |

画像の前処理には ImageMagick の `convert` コマンドを利用する。

**画像処理エンジンについての補足**

株式会社テクノホライズン提供の Linux 版 SkinDiagnosisSystem2 も検証したが、今回の Ubuntu 22.04 LTS 環境では解析結果として「-1」が返却され、正常な 7 項目の解析結果を取得できなかった。
一方、Windows 版 SkinDiagnosisSystem2.exe ＋ Wine 構成では、旧 Windows Server 2008 環境と同一の診断結果を取得できており、現行環境でも安定動作している。
そのため、現行の延命運用では、**Windows 版 SkinDiagnosisSystem2.exe ＋ Wine 構成**を採用する。

**※ Apache は使用していない**。PHP の配信は nginx → PM2 管理の PHP Built-in Server が担う。

---

## 2. OS / ミドルウェア バージョン

現行環境で確認されているバージョン。

| 項目 | バージョン |
| --- | --- |
| OS | Ubuntu 22.04 LTS (Jammy Jellyfish) |
| nginx | 1.18.0 (Ubuntu) |
| PHP | 8.3.30 (CLI / built-in server) |
| MySQL | 8.0.45 |
| Node.js | v20.x（nvm で管理） |
| PM2 | 6.x |
| Wine | 6.0.3 |
| Xvfb | xvfb-run 同梱 |
| ImageMagick | 6.8.9-10 Q16 (`/usr/local/bin/convert`) |

PHP 拡張は標準的な Ubuntu パッケージ（`php8.3-cli`, `php8.3-mysql`, `php8.3-mbstring`, `php8.3-gd`, `php8.3-zip`, `php8.3-xml`）を想定する。`libapache2-mod-php` は不要。

### 2.1 バージョンの互換性について

再構築時のバージョン選択の目安。

| ミドルウェア | 同一バージョンに揃えるべきか | 理由・注意点 |
| --- | --- | --- |
| PHP | 同一バージョン推奨（8.3.x） | PHP 8.x 系でも細かいバージョン差で挙動が変わることがある |
| MySQL | 同一メジャーバージョン（8.0.x）推奨 | 主要機能は互換性高いが、認証プラグイン等に差異あり |
| Wine | **同一バージョン（6.0.3）強く推奨** | Wine のバージョン差は画像解析結果に影響する可能性がある。旧環境と異なるバージョンを使う場合は必ず動作確認を実施すること |
| ImageMagick | **同一バージョン（6.8.9-10）強く推奨** | `convert` による画像クロップ処理が診断入力画像を生成するため、バージョン差で切り出し結果が変わると解析値に影響する可能性がある。近いバージョンでも動作確認必須 |

---

## 3. ディレクトリ配置（サーバー上の実体）

**重要：サーバー内フォルダー名と公開サブドメインの違い**

| 区分 | 値 |
| --- | --- |
| サーバー内フォルダー名 | `/home/skin/asp.hada-check.com/` |
| 公開サブドメイン（URL） | `https://app.hada-check.com/` |

フォルダー名は `asp.hada-check.com`、公開 URL は `app.hada-check.com` と異なる。現状フォルダー名を変更する必要はない（動作中のため）。nginx・SSL 証明書・DNS など、公開 URL として記載が必要な箇所は `app.hada-check.com` を使用する。

### 3.1 主要ディレクトリ一覧

| パス | 用途 |
| --- | --- |
| `/home/skin/asp.hada-check.com/` | アプリケーション本体（PM2 の cwd） |
| `/home/skin/asp.hada-check.com/client/` | クライアント（加盟店）向け画面 |
| `/home/skin/asp.hada-check.com/admin/` | 管理者向け画面 |
| `/home/skin/asp.hada-check.com/lib/` | 共通ライブラリ・設定・DB 接続・診断ロジック |
| `/home/skin/asp.hada-check.com/Smarty/` | テンプレートエンジン Smarty 本体 |
| `/home/skin/asp.hada-check.com/bin/SkinDiagnosisSystem/` | 画像解析エンジン (`SkinDiagnosisSystem2.exe`) と係数 INI |
| `/home/skin/asp.hada-check.com/files/uploaded_zip/` | クライアントがアップロードした ZIP の展開先 |
| `/home/skin/asp.hada-check.com/files/pdf_result/` | 生成された診断結果 PDF の保存先 |
| `/home/skin/asp.hada-check.com/user/` | クライアント別カスタマイズファイル（Git 管理対象外） |
| `/home/skin/.wine-skindiagnosis/` | 画像解析エンジン専用の Wine プレフィックス（skin 所有） |
| `/home/skin/.pm2/` | PM2 のログ・pid・dump ファイル |

### 3.2 user/ 配下のクライアント別フォルダー

`/home/skin/asp.hada-check.com/user/` 配下には、クライアント別のカスタマイズファイルが置かれている。

**Panasonic 系（クライアント ID=4, 21, 25）**

| フォルダー名 | クライアント ID | 用途 |
| --- | --- | --- |
| `user/panasonic/` | 4 | Panasonic 向けカスタマイズ（テンプレート・CSS・画像・ログイン処理） |
| `user/panasonicsbsc/` | 21 | Panasonic 定額利用サービス向け |
| `user/Panasonicpb/` | 25 | Panasonic 一般向けサービス向け |

各フォルダーの共通構成: `index.php`, `logout.php`, `login/`, `check/`, `templates/`, `common/`（JS・CSS）, `images/`

**クレシエール系（クライアント ID=10, 11）**

| フォルダー名 | クライアント ID | 用途 |
| --- | --- | --- |
| `user/crecher/` | 11 | クレシェール化粧品向けカスタマイズ（テンプレート・CSS・画像・ログイン処理） |
| `user/crecher2/` | 10 | クレシェール化粧品 第2サービス向け |

各フォルダーの共通構成: `index.php`, `logout.php`, `login/`, `check/`, `templates/`, `common/`（JS・CSS）, `images/pdf/`（PDF用画像）

**バックアップ対象について**

`user/` 配下は Git 管理対象外であるため、サーバーから直接バックアップを取得する必要がある。特に `user/crecher/images/`, `user/crecher2/images/`, `user/panasonic/images/` 等の画像ファイルは再生成できないため、バックアップ必須。

---

## 4. フロント nginx と公開 URL

### 4.1 概要

公開サブドメイン: `app.hada-check.com`（HTTPS）

- ポート 443（HTTPS）で本番運用中
- ポート 80（HTTP）はアクセスがあると自動的に 443 へ 301 リダイレクト
- SSL 証明書は Let's Encrypt（Certbot 管理）

nginx は受信したリクエストをすべて `http://127.0.0.1:8000`（PM2 が動かす PHP サーバー）へプロキシするだけのシンプルなリバースプロキシ。

### 4.2 実際の nginx 設定ファイル（現行）

- 設定ファイル: `/etc/nginx/sites-available/default`
- 有効化リンク: `/etc/nginx/sites-enabled/default`

現行の内容（実際のファイルより）:

```nginx
server {
    server_name app.hada-check.com;

    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cookie_path / /;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/app.hada-check.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/app.hada-check.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

server {
    # HTTP → HTTPS リダイレクト（Certbot 管理）
    if ($host = app.hada-check.com) {
        return 301 https://$host$request_uri;
    }
    listen 80;
    server_name app.hada-check.com;
    return 404;
}
```

### 4.3 DNS・SSL・ConoHa 側の設定

| 項目 | 内容 |
| --- | --- |
| DNS | `app.hada-check.com` → このサーバーの IP を指す A レコード |
| DNS 管理場所 | ConoHa の DNS 設定画面（または別途のドメイン管理業者） |
| SSL 証明書 | Let's Encrypt（Certbot が自動更新） |
| 証明書ファイル場所 | `/etc/letsencrypt/live/app.hada-check.com/` |
| 証明書自動更新 | `certbot renew`（systemd timer または cron で定期実行） |
| ConoHa 側の設定 | ConoHa VPS のセキュリティグループ（ファイアウォール）で TCP/80 と TCP/443 を開放 |

---

## 5. アプリ PHP サーバー（PM2 管理）

PHP 本体は `php -S localhost:8000 -t .` の形式で PHP 内蔵 Web サーバーとして起動される。プロセス管理は PM2 で行い、`skin` ユーザーで常駐する。

| 項目 | 値 |
| --- | --- |
| PM2 プロセス名 | `skin` |
| 実行ユーザー | `skin` |
| ワーキングディレクトリ | `/home/skin/asp.hada-check.com` |
| 起動コマンド | `bash -c "php -d upload_max_filesize=64M -d post_max_size=256M -S localhost:8000 -t ."` |
| ログ出力 | `/home/skin/.pm2/logs/skin-out.log` / `skin-error.log` |

---

## 6. 保存場所（データ）

### 6.1 ファイル系（ローカルディスク）

| 種別 | パス | 作成主体 | バックアップ要否 |
| --- | --- | --- | --- |
| アップロード ZIP 展開先 | `files/uploaded_zip/{クライアントID}_{日時}_{マイクロ秒}/` | `client/main/zip_upload.php` | 削除可（DB に結果保存済みなら中間ファイルは不要）|
| 診断結果 PDF | `files/pdf_result/client_{ID}_file_{連番}/` | `client/main/exec_make_pdf.php` | **バックアップ必須**（再生成は可能だが手間がかかる） |
| PDF 一時生成作業用 | `files/pdf_result_temp/`（定数定義のみ、ディレクトリ未使用） | `lib/config.php` で定義 | 現状未使用のため対応不要 |
| Smarty コンパイルキャッシュ | `Smarty/templates_c/`, `Smarty/cache/` | 自動生成（再生成可） | 削除可（自動再生成される） |
| PHP セッション | `/var/lib/php/sessions/`（所有者 `skin`） | PHP 標準のファイルハンドラ | 削除可（ログイン中ユーザーのセッションのみ） |

**`files/pdf_result_temp/` について**: `lib/config.php` に `FILE_EXPORT_TEMP_DIR` として定数定義されているが、現行コードでは当該定数を参照しているファイルは存在せず、ディレクトリ自体も作成されていない。現時点では未使用の定数定義である。

### 6.2 DB

MySQL 上に以下を保持する。

| DB 名 | 役割 |
| --- | --- |
| `admin` | システム全体の管理（管理者ユーザー、クライアント一覧、マスタ等） |
| `client_m` | クライアント共通マスタ（テンプレート元） |
| `c_{クライアント名}` | 各クライアント固有のユーザー・診断結果・CSV データ |

クライアントを追加すると、対応する `c_xxx` DB が新規作成される運用になっている。

**主要テーブルと用途**

| テーブル名 | DB | 用途 |
| --- | --- | --- |
| `t_client` | `admin` | クライアント一覧（クライアントID、会社名、DBname、dirName） |
| `t_admin` | `admin` | 管理者ユーザー情報 |
| `t_result` | `c_xxx` | 診断結果ヘッダ（ユーザー情報・問診回答 ans1〜20・画像解析結果 k_checker_score1〜7・肌タイプ・各種判定値・PDFパス） |
| `t_inported_file` | `c_xxx` | ZIPアップロード単位のファイル管理（file_id、ZIPファイル名、PDF生成済みフラグ） |
| `t_user` | `c_xxx` | 被験者ユーザー情報 |
| `t_customize` | `c_xxx` | クライアント別カスタマイズ設定 |
| `m_check_q` / `m_check_ans` | `c_xxx` | 問診設問・回答マスタ |
| `m_skin_type` 等 | `c_xxx` | 肌タイプ・コメント等のマスタ類 |

`t_result` が診断結果の中心テーブル。問診回答（ans1〜20）・画像解析結果7値（k_checker_score1〜7）・PDF出力情報（k_checker_img_path等）・各種判定結果がすべてこのテーブルに保存される。`t_inported_file` の `file_id` と `t_result.file_id` で紐づく。

---

## 7. 権限・実行ユーザー

| 対象 | 権限・ユーザー |
| --- | --- |
| アプリケーションファイル所有者 | `skin:skin` |
| PHP / PM2 実行ユーザー | `skin` |
| nginx 実行ユーザー | `www-data`（プロキシするだけなのでファイル書き込み不要） |
| `files/`, `files/pdf_result/`, `files/uploaded_zip/` | `skin:skin` / `0777`（PHP=`skin` が書き込み） |
| `Smarty/templates_c/`, `Smarty/cache/` | `skin:skin` / `0775` |
| `/home/skin/.wine-skindiagnosis/` | `skin:skin`（PHP の exec() も `skin` で動くので整合） |
| `/var/lib/php/sessions/` | `skin:skin` / `1733` 相当（sticky） |
| `user/` 配下 | `skin:skin` / `0664`（ファイル）、`0775`（ディレクトリ）推奨 |

nginx は静的ファイルを直接配信しないので（全部プロキシする）、nginx 側に読み権限を与える必要はない。

---

## 8. ネットワーク

| ポート | 種別 | 用途 |
| --- | --- | --- |
| TCP/443 | 公開（HTTPS） | nginx が受けて PHP サーバーへプロキシ。Let's Encrypt SSL |
| TCP/80 | 公開（HTTP） | nginx が 443 へ 301 リダイレクト（実コンテンツは返さない） |
| 127.0.0.1:8000 | 内部のみ | PHP 内蔵サーバー（外部非公開） |
| 127.0.0.1:3306 | 内部のみ | MySQL（外部非公開） |

- 外部 API との通信は行っていない（完結型）
- メール送信等の外部連携も現行は無し

---

## 9. 自動起動

| サービス | 自動起動方法 |
| --- | --- |
| nginx | `systemctl enable nginx`（systemd） |
| MySQL | `systemctl enable mysql`（systemd） |
| PM2（`skin` プロセス） | `pm2 save` + `pm2 startup systemd -u skin --hp /home/skin` で systemd ユニット生成 |

`pm2 save` を実行しないとサーバー再起動後に PM2 プロセス一覧が空になり、PHP サーバーが立ち上がらないので注意。

---

## 10. 監視・バックアップ

定期バックアップやジョブ監視は OS 側に仕組みを置いていないため、以下を手動または個別スクリプトで取得する。

| バックアップ対象 | 取得方法 | 復元方法 | 取得頻度（推奨） | 保存先 |
| --- | --- | --- | --- | --- |
| MySQL 全 DB | `mysqldump --all-databases` | `mysql < dump.sql` | 日次 | 外部ストレージ or ConoHa オブジェクトストレージ |
| `files/pdf_result/` | `tar czf pdf_result.tar.gz files/pdf_result/` | `tar xzf` で展開 | 週次または都度 | 同上 |
| アプリケーションコード | `git push` または `tar` | `git clone` または展開 | コード変更時 | Git リポジトリ |
| `/home/skin/.pm2/dump.pm2` | `pm2 save` 後にファイルコピー | `pm2 resurrect` | PM2 設定変更時 | 同上 |
| `user/` 配下 | `tar czf user.tar.gz user/` | `tar xzf` で展開 | 変更時 | 同上 |
| `bin/SkinDiagnosisSystem/` | `tar czf` で一式 | `tar xzf` で展開 | 変更時 | 同上 |

**削除してよいもの（容量逼迫時）**

| パス | 削除可否 | 注意 |
| --- | --- | --- |
| `files/uploaded_zip/` 内の古いフォルダー | 削除可 | DB に診断結果が保存されていれば中間ファイルは不要 |
| `Smarty/templates_c/`, `Smarty/cache/` | 削除可 | 自動再生成される |
| `/var/lib/php/sessions/` | 削除可 | ログイン中ユーザーが再ログインが必要になる |
| `files/pdf_result/` | **削除不可** | 再生成は可能だが生成済みPDFは貴重なデータ |
| `user/` 配下 | **削除不可** | クライアント別テンプレート・画像（再生成不可） |
| `bin/SkinDiagnosisSystem/` | **削除不可** | 画像解析エンジン本体 |
