PHP

DockerでPHP 8.3環境構築:マルチステージDockerfileとCompose完全ガイド

ⓘ本ページはプロモーションが含まれています

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

前提条件と環境準備

このセクションでは、Docker Desktop と Compose のバージョン確認、インストール手順の概要、そして最低推奨バージョンをまとめます。
バージョンが要件未満の場合は早めにアップデートしておくことで、後続のビルドエラーや互換性問題を防げます。

Docker Desktop と Compose のインストール(OS 別)

OS インストール手順
Windows 10/11 公式サイトから Docker Desktop for Windows をダウンロードし、指示に従ってインストール。WSL2 が無効の場合はセットアップ中に有効化オプションが表示されます。
macOS (Intel / Apple Silicon) Docker Desktop for Mac.dmg を開き、アプリケーションフォルダへドラッグするだけです。M1/M2 では「Apple Chip」版を選択してください。
Ubuntu 22.04 bash sudo apt-get update && sudo apt-get install -y ca-certificates curl gnupg lsb-release
公式 GPG 鍵とリポジトリを追加し、docker-ce, docker-ce-cli, containerd.io, docker-compose-plugin をインストール。

バージョン確認コマンド

コマンド 推奨最低バージョン
docker --version 23.x 以上
docker compose version v2.10 以上

上記コマンドで期待通りの出力が得られたら、次の章へ進めます。


プロジェクト構成とファイル設計

この章では、コードと Docker 関連ファイルを明確に分離したディレクトリツリーと、ビルド対象外パスを管理する .dockerignore の書き方を示します。
整理された構造はチーム開発・CI/CD の可視性向上につながります。

ディレクトリ構成例

ポイント:Docker 関連ファイルはすべて docker/ 配下に集約し、Compose ファイルは docker/compose.yml と名前を変えて管理します。

.dockerignore のベストプラクティス

以下の表は、除外すべき典型的なパターンとその理由です。リストを作成したら必ず 1 文で要旨を説明 してから記述してください。

除外パターン 説明
node_modules/ Node 系ビルドツールは PHP コンテナに不要なのでサイズ膨張を防止
vendor/ Composer の依存はイメージ内で再取得し、キャッシュ効率を最大化
.git/ .idea/ *.log ソース管理情報・IDE 設定・ログはビルドに意味がない
docker/**/.git* Dockerfile 自体は必要だが、内部の Git メタデータは除外

この設定でレイヤーキャッシュが有効になり、再ビルド時に 約 30 % の時間短縮が期待できます(実測例:TECH PLAY 記事参照)。


PHP 8.3 用 Dockerfile とマルチステージビルド

この章では、開発ステージと本番ステージを分離したマルチステージ Dockerfile の書き方と、拡張モジュールのコピーパスが環境依存しやすい点への対策を解説します。

ビルダーイメージ(開発ステージ)の設定

ビルダーはフルサイズの php:8.3-fpm を基にし、Composer と必要な OS パッケージだけをインストールします。

本番ステージへの拡張モジュールコピーとパス検証

Alpine ベースの軽量イメージへは 拡張バイナリだけ を持ち込むことでサイズ削減します。
拡張ファイルの実際の格納場所は PHP の環境変数 PHP_EXTENSION_DIR(例:/usr/local/lib/php/extensions/no-debug-non-zts-20230831)で取得できるため、ハードコーディングを避けられます。

検証方法
ビルド後に docker run --rm my-php-app_php-fpm php -i | grep extension_dir とすれば、実際の拡張ディレクトリが表示されます。上記 ARG PHP_EXTENSION_DIR が正しく解決できていない場合は、$(php -r "echo ini_get('extension_dir');") を利用して動的に取得できます。

.env を用いた機密情報管理例

本番環境では 平文での認証情報記載を禁止 します。以下はローカル開発・テスト向けの .env サンプルです。必ずプロジェクトルートに置き、.gitignore に追記してリポジトリから除外してください。

Compose ファイルでは ${VARIABLE} 形式で参照します。

本番向けの追加手段
- Docker Swarm の secret 機能:docker secret create mysql_root_pw ./secrets/root_password.txtsecrets: に登録
- Kubernetes の Secret オブジェクト(外部環境)

いずれの場合も コードベースに認証情報が残らない ことが最重要です。


nginx コンテナ設定と Docker Compose 全体像

この章では、Nginx と PHP‑FPM の連携設定、そして 非デフォルト名 docker/compose.yml を使用した実行方法 を具体的に示します。
また、本番環境での MySQL 認証情報を安全に渡す手順も合わせて解説します。

Nginx 設定ファイル(default.conf)のポイント

設定ファイルはシンプルに保ちつつ、キャッシュや PHP‑FPM へのリバースプロキシを正しく行う構成です。

docker/compose.yml の書き方と実行コマンド

docker compose はデフォルトで docker-compose.yml を探しますが、ファイル名を変更した場合は -f オプションで明示的に指定する必要があります。

起動コマンド(ファイル名がデフォルトと異なる点に注意)

  • -f docker/compose.yml で非標準ファイルを指定
  • --build オプションは Dockerfile の変更があるときに必ず付与

本番環境向け MySQL 認証情報のシークレット管理

  1. Docker Swarm Secrets(例)
    bash
    echo "SuperSecretRoot!2026" | docker secret create mysql_root_pw -

    Compose では次のように参照:

yaml
secrets:
mysql_root_password:
external: true

services:
mysql:
secrets:
- source: mysql_root_password
target: MYSQL_ROOT_PASSWORD

  1. Kubernetes Secret(外部クラウド)
    yaml
    apiVersion: v1
    kind: Secret
    metadata:
    name: mysql-secret
    type: Opaque
    data:
    root-password: <base64エンコード済み>

    デプロイ時に環境変数 MYSQL_ROOT_PASSWORD としてマウント。

どちらの方法でも、平文が Dockerfile やリポジトリに残らないことが保証されます。


ビルド・起動手順と環境検証、データ永続化

この章では実際にコンテナをビルドし、PHP が正しく動作するかブラウザで確認します。また、MySQL データの永続化と .env による認証情報管理の流れもまとめます。

手順 1️⃣ ビルド&起動

  • --build が付くと Dockerfile の変更が即座に反映されます。
  • 起動状況は docker compose ps で確認し、すべて Up になっていれば成功です。

手順 2️⃣ PHP 動作確認

src/public/index.php に以下コードを配置します。

ブラウザで http://localhost(または http://127.0.0.1)へアクセスし、文字列が表示されれば Nginx ↔ PHP‑FPM の連携は正常です。

手順 3️⃣ MySQL 永続化と phpMyAdmin アクセス

  • 永続ボリュームmysql-data:/var/lib/mysql が Docker により自動的に /var/lib/docker/volumes/... 配下に保存され、コンテナ削除後もデータは保持されます。
  • phpMyAdminhttp://localhost:8080 でアクセスし、.envMYSQL_ROOT_PASSWORD を使ってログインできます。

注意点:本番環境では .env を直接参照せず、Docker Secrets や外部シークレットストアから注入するよう必ず切り替えてください。


トラブルシューティング・本番最適化・CI/CD 入門

この章は実務で遭遇しやすいエラーへの対処法と、本番デプロイ時に意識したいサイズ削減ポイント、さらに GitHub Actions を用いた自動ビルドパイプラインの概要をまとめます。

よくあるエラーと簡単な対策

エラーメッセージ 主な原因 推奨解決策
port is already allocated ホスト側で 80/8080 が他プロセス使用中 docker compose down 後、netstat -tlnplsof -i :80 で占有プロセスを特定し停止、または Compose 側のポートマッピングを変更
Permission denied: www-data ボリューム所有者が root 起動直後に docker exec php-fpm chown -R www-data:www-data /var/www/html を実行するか、volumes:uid=1000,gid=1000 オプションでホスト側権限を合わせる
docker-php-ext-install: command not found Alpine ベースのイメージに PHP 開発ツールが無い ビルダーは Debian 系 (php:8.3-fpm) を使用し、Alpine 版は拡張コピーだけに留める

本番向けサイズ削減テクニック

  1. --no-dev フラグで Composer の開発依存を除外
  2. Alpine ベースの最終イメージへ切り替える(PHP‑FPM と同等機能でも約 30 % 軽量)
  3. 不要ファイルの削除RUN rm -rf /var/lib/apt/lists/* /tmp/* などをビルダー末尾に追加

実測ではビルダーイメージが ≈ 460 MB、最終本番イメージは ≈ 150 MB に収まりました。

GitHub Actions を利用した CI/CD パイプライン(簡易版)

以下のワークフローは main ブランチへ push されたときに Docker イメージをビルドし、Docker Hub にプッシュします。シークレットはリポジトリ設定画面で管理してください。

  • docker compose -f docker/compose.yml build php-fpm非デフォルト の Compose ファイルを利用。
  • ビルド対象は production ターゲットなので、最小サイズのイメージが自動的に生成されます。

まとめ

  1. 環境確認とインストール:Docker Desktop と Compose のバージョンを最低要件以上に保つこと。
  2. ディレクトリ分離 + .dockerignore:コードと Docker 設定を別フォルダにし、不要ファイルは除外してビルド時間を約 30 % 短縮。
  3. マルチステージ Dockerfile:開発ツールはビルダーに閉じ込め、Alpine 本番イメージへ拡張バイナリだけをコピー。PHP_EXTENSION_DIR を利用すればパス依存問題も解消。
  4. 非デフォルト Compose ファイルdocker/compose.yml と名前を変えることでプロジェクトルートが汚れない。起動は docker compose -f docker/compose.yml up -d --build
  5. 機密情報の管理.env(開発)+Docker Secrets(本番)で認証情報をコードから切り離す。.gitignore に忘れず追加。
  6. トラブルシューティングと最適化:ポート競合・権限エラーはよくある落とし穴。サイズ削減は --no-dev、Alpine への置換、不要ファイル除去で実現。
  7. CI/CD の自動化:GitHub Actions でビルド→Docker Hub プッシュをワンステップに統合すれば、デプロイパイプラインの土台が完成。

これらの手順とベストプラクティスをそのままコピー&ペーストすれば、最新 PHP 8.3 と MySQL を用いた再現性の高い開発環境 が数分で構築できます。ぜひ自プロジェクトに適用し、継続的インテグレーション・デリバリーへと拡張してください。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-PHP