この記事では、DockerおよびDocker Composeを使用して、PHP(Apacheモジュール)、MariaDB、Redisを含む本格的なLAMP開発環境を構築する手順について解説します。コンテナ化された環境により、依存関係の管理や環境の移植性が大幅に向上します。
PHPカスタムイメージの作成
まず、公式のPHPイメージをベースに、必要な拡張機能やツールを組み込んだカスタムイメージを作成します。これにより、本番環境に近い開発環境を迅速に再構築できるようになります。
Dockerfileの記述
以下のDockerfileでは、PHPの実行に必要な画像処理ライブラリやデータベース接続ドライバ、そしてパッケージ管理ツールであるComposerをインストールします。
FROM php:8.2-apache
# 必要なライブラリと拡張モジュールのインストール
RUN apt-get update && apt-get install -y \
libzip-dev \
libonig-dev \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
&& rm -rf /var/lib/apt/lists/*
# GD拡張(画像処理)の設定とインストール
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
# データベースとその他の拡張機能のインストール
RUN docker-php-ext-install -j$(nproc) pdo pdo_mysql mysqli zip
# Redis拡張モジュールのインストール
RUN pecl install redis && docker-php-ext-enable redis
# Composerのインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Apacheの設定(mod_rewrite有効化)
RUN a2enmod rewrite
# 設定ファイルのコピーと仮想ホストの設定
COPY ./php.ini /usr/local/etc/php/conf.d/custom.ini
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf
docker-php-ext-installコマンドを使用することで、PHPのコア拡張を容易に追加できます。また、PECL経由で提供されているRedis拡張もインストールし、有効化しています。Composerは公式イメージからバイナリをコピーすることで、インストールプロセスを簡素化しています。
Docker Composeによるオーケストレーション
次に、アプリケーションサーバー(PHP)、データベース(MariaDB)、キャッシュサーバー(Redis)の各コンテナを一元的に管理するためのdocker-compose.ymlファイルを作成します。
docker-compose.ymlの定義
version: '3.8'
services:
# PHP/Apache Webサーバー
web:
build: ./docker/php
container_name: dev_app_server
restart: always
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
depends_on:
- db
- cache
# MariaDBデータベース
db:
image: mariadb:latest
container_name: dev_database
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_secret
MYSQL_DATABASE: app_db
MYSQL_USER: app_user
MYSQL_PASSWORD: user_pass
ports:
- "3306:3306"
volumes:
- db_storage:/var/lib/mysql
# Redisキャッシュサーバー
cache:
image: redis:alpine
container_name: dev_cache_server
restart: always
ports:
- "6379:6379"
volumes:
db_storage:
設定のポイント
- ボリュームマウント:
./src:/var/www/htmlとすることで、ホストマシンのソースコードをコンテナ内のApacheドキュメントルートに同期させます。これにより、ホスト側で行ったコードの変更が即座に反映されます。 - 名前付きボリューム: データベースのデータ永続化には、
db_storageという名前付きボリュームを使用します。コンテナを削除してもデータベースの内容は保持されます。 - ネットワーク: 同じ
docker-compose.ymlファイル内で定義されたサービスは、自動的に同じDockerネットワークに所属し、相互に通信が可能になります。
コンテナ間の通信とネットワーク
Docker Composeで作成されたコンテナ同士が通信する場合、IPアドレスを直接指定する代わりに、サービス名をホスト名として使用します。
例えば、PHPアプリケーションからデータベースに接続する場合、ホスト名としてlocalhostや127.0.0.1を使用すると、PHPコンテナ自身を指してしまうためエラーになります。代わりに、docker-compose.ymlで定義したサービス名dbをホストとして指定します。
// 正しい接続ホスト名
$host = 'db';
// Redisへの接続
$redis = new Redis();
$redis->connect('cache', 6379);
また、ホストマシンからデータベースに接続する場合(例:Sequel ProやMySQL Workbenchを使用する場合)は、localhostまたは127.0.0.1と、ポートマッピングで設定したホスト側のポート(例:3306)を使用して接続します。
開発時のトラブルシューティング
フレームワークやライブラリによっては、デバッグモードを有効にするために特定のIPアドレスをホワイトリストに登録する必要があります。コンテナ内で実行されているPHPから見た「外部」のIPアドレスは、ホストマシンのIPアドレスではなく、DockerのゲートウェイIP(通常は172.17.0.1や、Docker Composeネットワーク内のゲートウェイ)になることがあります。
開発中にアクセス拒否エラーが発生する場合は、該当するフレームワークの設定ファイルで、DockerネットワークのゲートウェイIPや*(全許可)をテスト用に許可リストに追加することを検討してください。