PHPアプリケーションのコンテナ化
本番環境向けのPHP Dockerfileを作成します。
「PHPアプリケーションのコンテナ化」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。
PHPをコンテナ化する理由
PHPを再現性のある形でデプロイするには、コードとともに正確なインタープリターのバージョン、拡張機能、OSライブラリを固定する必要があります。Dockerイメージを使えば、ノートPC、CI、本番環境のすべてで同じphp -vと同じext-*のセットを使用できます。
このレッスンでは、本番環境で使用できるイメージを構築します。PHP-FPM、必要な拡張機能だけ、調整済みの設定、非rootユーザー、ヘルスチェックを含めます。
FPMとApacheのベースイメージ
公式のPHPイメージには複数の種類があります。nginx/traefikの背後で動かす本番Webアプリケーションには、php:8.3-fpm-alpine(小容量)またはphp:8.3-fpm(Debian、glibcを使用し、ネイティブライブラリで問題が起きにくい)を推奨します。
cli— ワーカー、キュー、cronfpm— FastCGIプロセスマネージャー。nginxと組み合わせますapache— Apacheを内蔵。便利ですが、より重くなります
マイナーバージョンを固定してください。本番環境では決して:latestを使用しないでください。
# Base image choice in your Dockerfile
FROM php:8.3-fpm-alpine AS base
# Why alpine? ~30MB base vs ~140MB Debian.
# Tradeoff: musl libc, occasional native-extension friction.拡張機能をインストールする
これらのイメージ内でapt install php-xxxを実行してはいけません。組み込みのヘルパーであるdocker-php-ext-install、docker-php-ext-configure、peclを使用してください。install-php-extensionsスクリプト(mlocati)は、必要な開発用ヘッダーを自動的に取得してくれる、事実上のショートカットです。
FROM php:8.3-fpm-alpine
# Grab the helper that resolves build deps automatically
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions \
pdo_mysql \
opcache \
intl \
zip \
redis \
bcmathイメージ内のComposer
インストーラーをcurlするのではなく、公式イメージからComposerのバイナリをコピーしてください。本番環境では--no-devと--optimize-autoloaderを付けてcomposer installを実行します。また、ソースの変更とは独立して依存関係のレイヤーをキャッシュできるよう、最初にcomposer.json/composer.lockだけをコピーしてください。
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app
# Cache-friendly: deps layer invalidates only when lock changes
COPY composer.json composer.lock ./
RUN composer install \
--no-dev \
--no-scripts \
--no-autoloader \
--prefer-dist
COPY . .
RUN composer dump-autoload --optimize --classmap-authoritativephp.iniを調整する
ベースイメージにはphp.ini-productionとphp.ini-developmentのテンプレートが含まれています。本番用のテンプレートを有効にしてから、独自の上書き設定をconf.dに配置してください。このディレクトリは最後にマージされるため、設定が優先されます。
本番環境で重要な値は、opcache.enable=1、opcache.validate_timestamps=0(イメージ内のコードが不変であるため)、適切なmemory_limitです。
# Activate production ini
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# Custom overrides win because conf.d loads last
COPY docker/php/zz-app.ini $PHP_INI_DIR/conf.d/zz-app.iniOPcacheの上書きファイル
これは本番環境で最も大きな効果をもたらす設定です。validate_timestamps=0にすると、PHPはリクエストごとにファイルの状態を確認しません。ただし、変更をデプロイするにはイメージを必ず再ビルドする必要があります。これは、不変コンテナにとってまさに望ましい動作です。
; docker/php/zz-app.ini
memory_limit = 256M
expose_php = Off
opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 256
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.validate_timestamps = 0
opcache.preload = /app/preload.php
opcache.preload_user = www-data非rootで実行する
このイメージにはすでにwww-dataが定義されています。FPMをrootで実行すると、攻撃対象領域が不必要に広がります。書き込み可能なパス(キャッシュ、ログ)の所有権を設定し、CMDの前にUSERでユーザーを切り替えてください。
FPMのマスタープロセスは特権ポートで待ち受ける必要があるでしょうか。いいえ。FPMは9000番ポート(非特権ポート)で待ち受けるため、非rootで簡単に実行できます。
# Make runtime-writable dirs owned by the runtime user
RUN chown -R www-data:www-data /app/var /app/storage 2>/dev/null || true
USER www-data
EXPOSE 9000
CMD ["php-fpm"]ヘルスチェック
オーケストレーターには、プロセスが存在するだけでなく、FPMが実際に稼働していることを示すシグナルが必要です。cgi-fcgiを使うと、FPMの/statusまたは/pingエンドポイントにpingを送信できます。まずFPMのプールでpm.status_pathとping.pathを有効にしてください。
# In www.conf pool config:
; ping.path = /ping
; ping.response = pong
# Dockerfile HEALTHCHECK using cgi-fcgi
RUN install-php-extensions @composer >/dev/null 2>&1 || true
HEALTHCHECK --interval=10s --timeout=3s --retries=3 \
CMD SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET \
cgi-fcgi -bind -connect 127.0.0.1:9000 || exit 1Dockerfileを組み立てる
ここでは、一貫性のある単一ステージの本番用Dockerfileを示します。次のレッスンでは、ビルドツールを取り除くためにマルチステージに分割します。順序に注目してください。依存関係 → 設定 → ソース → オートロード → ユーザー切り替え。
FROM php:8.3-fpm-alpine
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions pdo_mysql opcache intl zip redis
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /app
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY docker/php/zz-app.ini $PHP_INI_DIR/conf.d/
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
COPY . .
RUN composer dump-autoload --optimize --classmap-authoritative && \
chown -R www-data:www-data /app/var
USER www-data
EXPOSE 9000
CMD ["php-fpm"]ビルドを検証する
ビルド後は、実際にイメージに含まれたものを簡単に確認します。PHPのバージョン、読み込まれた拡張機能、そしてOPcacheの検証が無効になっていることを確認します。短いCLIスクリプトで、アプリが依存する実行環境の契約を確認できます。
<?php
// Run inside the container: php verify.php
echo 'PHP ' . PHP_VERSION . PHP_EOL;
$required = ['pdo_mysql', 'opcache', 'intl', 'zip'];
foreach ($required as $ext) {
printf("%-12s %s\n", $ext, extension_loaded($ext) ? 'OK' : 'MISSING');
}
var_dump((bool) ini_get('opcache.enable'));
?>ビルドコンテキストを整理する
.dockerignoreを使うとビルドコンテキストを小さく保ち、シークレットやvendorの肥大化がイメージに入り込んだり、キャッシュを無効化したりするのを防げます。vendor、VCS、envファイル、ローカル用ツールを除外してください。
# .dockerignore
.git
.gitignore
vendor/
node_modules/
.env
.env.*
tests/
*.md
docker-compose*.yml
storage/logs/*
var/cache/*確認
本番用イメージでopcache.validate_timestamps=0を設定するのはなぜですか?
まとめ
本番用のPHP-FPMイメージを構築しました。8.3-fpm-alpineベースのバージョンを固定し、インストーラースクリプトで必要な拡張機能だけをインストールし、Composerとキャッシュ済みの依存関係をそれぞれ専用レイヤーにコピーし、OPcacheのオーバーライドを含む本番用php.iniを有効にし、www-dataに切り替え、FPMのヘルスチェックを追加しました。
重要な習慣: バージョンを固定する、依存関係のレイヤーをキャッシュする、非rootユーザーで実行する、タイムスタンプ検証を無効にする、そして.dockerignoreでビルドコンテキストをスリムに保つことです。
よくある質問
「PHPアプリケーションのコンテナ化」レッスンは無料ですか?
はい。「PHPアプリケーションのコンテナ化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。
「PHPアプリケーションのコンテナ化」で何を学びますか?
本番環境向けのPHP Dockerfileを作成します。 ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
PHP Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「PHPアプリケーションのコンテナ化」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このPHP Academyレッスンでコードを書いて実行できますか?
はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- PHPアプリケーションのコンテナ化
- マルチステージビルドと最適化
- ローカル環境向けDocker Compose
- GitHub ActionsによるCI/CD