概要
DockerでPHP8.3 + Apache + MariaDB の構築してみました。
windowsのWSL2・Ubuntu環境になります。
自分用のメモ的な記事になるので説明不足の点も多いですがご了承を。
ディレクトリ構成
.
├── mariadb/
│ ├── init/
│ │ └── init.sql
│ └── my.cnf
├── php/
│ ├── Dockerfile
│ └── php.ini
├── src/
│ └── index.php
└── compose.yaml
compose.yamlの設定を確認
コンテナをそれぞれ定義します
services:
php: # PHP+Apacheのサービス
build: ./php # コンテナのイメージを./phpディレクトリからビルド
container_name: apache_php # コンテナ名
user: "${UID_GID:-1000:1000}" # ホストマシンと同じユーザー権限でコンテナ内のプロセスを実行
volumes:
- ./src:/var/www/html
ports:
- "80:80" # ホストのポート:コンテナのポート
db:
image: mariadb:11.2.5 # MariaDBイメージのバージョンを指定
container_name: mariadb
environment: # Compose内の環境変数を指定
- MYSQL_ROOT_PASSWORD=rootpass
- MYSQL_DATABASE=database
- MYSQL_USER=user
- MYSQL_PASSWORD=password
- TZ=Asia/Tokyo
ports:
- "3306:3306"
volumes:
- type: volume
source: db-store # 定義済みのボリュームdb-storeを使用
target: /var/lib/mysql # MariaDBのデータディレクトリにマウント (データ永続化)
- type: bind
source: ./mariadb/my.cnf # ホスト側で設定を記述
target: /etc/mysql/conf.d/my.cnf # MariaDB の設定ファイルとしてマウント
- type: bind
source: ./mariadb/init # 初期化時にテーブルの作成やデータの挿入を行う
target: /docker-entrypoint-initdb.d
depends_on:
- php # PHPコンテナが起動した後にMariaDBコンテナを起動
pma:
image: phpmyadmin/phpmyadmin
container_name: phpmyadmin
environment:
- PMA_ARBITRARY=1 # 任意のホストへの接続を許可
- PMA_HOST=db # データベースのサービス名を指定
- PMA_USER=user # データベースユーザー名
- PMA_PASSWORD=password # データベースユーザーのパスワード
- TZ=Asia/Tokyo
ports:
- "8080:80"
depends_on:
- db
mailhog:
image: mailhog/mailhog
container_name: mail_server
ports:
- "8025:8025"
- "1025:1025"
volumes:
db-store: # MariaDBのデータを保存するためのボリューム
mariadbコンテナの初期化時にテスト用のテーブル作成とレコード挿入を行っています。
MariaDBの場合、/docker-entrypoint-initdb.d/ディレクトリに配置された.sqlファイルは、コンテナ起動時に自動的に実行されます。
CREATE TABLE IF NOT EXISTS test (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO test (name) VALUES
('TOM'),
('BOB');
コンテナイメージのビルド
Dockerイメージを作成するためのDockerfileをそれぞれ作成します。
今回でいうとPHPサービスのイメージを詳細に設定します。
FROM php:8.3-apache
# パッケージリストを更新し必要なライブラリ・ツールをインストール
# 最後にPHP拡張機能をインストール
# docker-php-ext-installは、PHP公式Dockerイメージに含まれるスクリプト
RUN apt-get update && apt-get install -y \
libzip-dev \
zip \
unzip \
git \
&& apt-get clean \
&& docker-php-ext-install zip pdo_mysql mysqli
# PHPの設定ファイルをホストからイメージ内にコピー
COPY php.ini /usr/local/etc/php/
# Composerのインストール
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php --install-dir=/usr/local/bin --filename=composer \
&& php -r "unlink('composer-setup.php');"
# ユーザーを作成する
RUN useradd -m -u 1000 -g www-data ww-data
# www-data ユーザーに変更
USER www-data
# ドキュメントルートを設定
WORKDIR /var/www/html
ライブラリ・ツールの補足
- RUN apt-get update:パッケージリストを最新の状態に更新
- apt-get install -y:必要なパッケージをインストール
- libzip-dev:zip拡張機能をコンパイルするために必要な開発ライブラリ
- zip、unzip:圧縮ファイルを作成・解凍するためのコマンドラインツール
- git:ソースコードの管理や外部リポジトリからの取得に使用
- apt-get clean:パッケージキャッシュを削除して、イメージのサイズを減らす
インストールするPHP拡張機能の補足
- zip:ZIP圧縮ファイルを扱うためのPHP拡張機能
- pdo_mysql:MySQLデータベースと連携するためのPDO(PHP Data Objects)ドライバ
- mysqli:MySQLデータベースと連携するための拡張機能です。mysql_*関数に対応
Composerのインストール
ComposerはDockerイメージを利用するなど色々方法はあると思いますが、composer公式サイトのインストール方法を参考にしました。(https://getcomposer.org/download/)
curlでComposerのインストーラーを取得し、PHPで実行します。
--install-dir=/usr/local/bin
でComposerを/usr/local/binにインストールします。
--filename=composer
で、実行ファイル名をcomposerに設定します。これがないとコンテナ内でcomposerコマンドが使えません。
MariaDBの設定
MariaDBの設定はmy.cnfに記述しています。
# クライアントアプリケーション(mysqlコマンドラインなど)が使用するデフォルトの文字セットを指定
[client]
default-character-set=utf8mb4
# mysqlコマンドラインクライアントのデフォルトの文字セットを指定
[mysql]
default-character-set=utf8mb4
# サーバーのデフォルトの文字セットと照合順序を設定
# character-set-server: サーバーのデフォルトの文字セット
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
コンテナを作成
docker compose up -d
でコンテナを作成しsrc/index.phpを下記のように記述しPHPとMariaDBが正常に動作しているか確認してください。確認URL:http://localhost/
<?php
// データベース接続情報
$host = 'db'; // ホスト名
$dbname = 'database'; // データベース名
$username = 'user'; // ユーザー名
$password = 'password'; // パスワード
// データベース接続
try {
$dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("データベース接続エラー: " . $e->getMessage());
}
// データ取得クエリ
try {
$sql = "SELECT * FROM test";
$stmt = $pdo->query($sql);
// テーブルのデータがあるか確認
if ($stmt->rowCount() > 0) {
echo "<table border='1' cellpadding='5' cellspacing='0'>";
echo "<tr><th>ID</th><th>Name</th></tr>";
// データを一覧表示
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "<tr>";
echo "<td>" . htmlspecialchars($row['id']) . "</td>";
echo "<td>" . htmlspecialchars($row['name']) . "</td>";
echo "</tr>";
}
echo "</table>";
} else {
echo "テーブルにデータがありません。";
}
} catch (PDOException $e) {
die("データ取得エラー: " . $e->getMessage());
}
phpinfo(); // 現在のPHPの設定状態を確認する。
?>
メール送信
PHPでメール送信の機能を実装する機会も多いと思います。メールテストツールでmailhogのコンテナを作成してるので試しに簡単なメール送信機能を作ってみました。
PHPのライブラリであるPHPMailerを使います。とりあえずcomposerでインストールします。
# phpサービスのコンテナにまず入る
$ docker compose exec php /bin/bash
# PHPMailerをインストール
$ composer require phpmailer/phpmailer
下記のphpファイルを用意。/srcフォルダに設置してブラウザにアクセスして「メール送信成功」と表示されれば成功。http://localhost:8025/ にアクセスしてメールの内容も確認してみてください。
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
$mail->CharSet = 'UTF-8';
try {
// SMTP 設定
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->Host = 'mailhog'; // Docker Compose のサービス名
$mail->SMTPAuth = false;
$mail->Port = 1025;
// 送信者情報
$mail->setFrom('from@example.com', '送信元');
$mail->addAddress('to@example.com', '送信先');
// メール内容
$mail->isHTML(true);
$mail->Subject = 'テスト件名';
$mail->Body = '<h1>これはテストメールです</h1>';
$mail->AltBody = 'テストメール';
$mail->send();
echo 'メール送信成功';
} catch(Exception $e) {
echo "メッセージを送信できませんでした。 Mailer Error: {$mail->ErrorInfo}";
}
参考文献
PHPMailer
https://github.com/PHPMailer/PHPMailer