同じ「学生一覧画面」を Docker で作る手順です。XAMPPを入れずに docker compose up 一発で Apache + MySQL が立ち上がります。
これは3部作の3本目です(XAMPP GUI編 / XAMPP for Linux・CLI編 / Docker編)。ゼロから作るので自分でコードを書けます。だからDB接続先を localhost ではなく サービス名 db にして、素直に分離構成にできるのがポイント(Dockerの王道)。
ファイル構成(5つ・全部1フォルダ内)
myportal/
├── docker-compose.yml # コンテナ2つ(web/db)の定義
├── Dockerfile # PHPにmysqli拡張を追加
├── init.sql # DB初期化(自動実行される)
├── db.php # DB接続(接続先は "db")
└── manage_students.php # 学生一覧画面(ゴール)
XAMPPの「Apache起動」「MySQL起動」「phpMyAdminでSQL実行」が、まとめて docker compose up に置き換わります。
ステップ1: プロジェクトフォルダ
mkdir -p ~/myportal && cd ~/myportal
ステップ2: init.sql(DB初期化・自動実行)
CREATE DATABASE は不要(composeの MYSQL_DATABASE で作られ、その中でこれが実行される)。
CREATE TABLE students (
s_id VARCHAR(20) PRIMARY KEY,
name VARCHAR(100) NOT NULL,
department VARCHAR(50),
semester INT,
email VARCHAR(100)
);
INSERT INTO students (s_id, name, department, semester, email) VALUES
('ktu1', 'Jack', 'MECH', 8, 'jack@example.com'),
('ktu2', 'Daniel', 'ECE', 2, 'daniel@example.com'),
('ktu3', 'Harry', 'IT', 4, 'harry@example.com');
ステップ3: Dockerfile
PHP公式イメージには mysqli が無いので追加します。
FROM php:8.2-apache
RUN docker-php-ext-install mysqli
ステップ4: docker-compose.yml
XAMPPの「Apache + MySQL」の2本立てを、そのままコンテナ2つで表現。
services:
web:
build: .
ports:
- "8080:80" # ブラウザ → http://localhost:8080
volumes:
- ./:/var/www/html # コードを反映(編集が即時に効く)
depends_on:
- db
db:
image: mariadb:10.4
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
MYSQL_DATABASE: myportal
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro # 自動実行
- dbdata:/var/lib/mysql
volumes:
dbdata:
web と db は自動作成される同じネットワーク上にいて、サービス名 db で名前解決できます。
ステップ5: db.php(Dockerの肝)
接続先が localhost ではなく db(サービス名)。
<?php
$servername = "db"; // ← XAMPP版は "localhost"。Dockerはサービス名
$username = "root";
$password = "";
$dbname = "myportal";
$con = mysqli_connect($servername, $username, $password, $dbname);
if (!$con) {
die("接続失敗: " . mysqli_connect_error());
}
?>
ステップ6: manage_students.php(XAMPP版と同一)
<?php include 'db.php'; ?>
<!DOCTYPE html>
<html lang="ja">
<head><meta charset="UTF-8"><title>学生管理</title></head>
<body>
<h1>学生一覧</h1>
<table border="1" cellpadding="8">
<tr><th>学籍番号</th><th>氏名</th><th>学科</th><th>セメスター</th><th>メール</th></tr>
<?php
$result = mysqli_query($con, "SELECT * FROM students ORDER BY s_id");
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>";
echo "<td>".htmlspecialchars($row['s_id'])."</td>";
echo "<td>".htmlspecialchars($row['name'])."</td>";
echo "<td>".htmlspecialchars($row['department'])."</td>";
echo "<td>".htmlspecialchars($row['semester'])."</td>";
echo "<td>".htmlspecialchars($row['email'])."</td>";
echo "</tr>";
}
?>
</table>
</body>
</html>
ステップ7: 起動(XAMPPの「Start」相当)
cd ~/myportal
docker compose up -d --build
初回はイメージDL+ビルドで少し待ちます。init.sql も自動で流れます。
ステップ8: 動作確認
curl http://localhost:8080/manage_students.php
ブラウザなら http://localhost:8080/manage_students.php。3名が出れば完成。
操作コマンド早見表(XAMPP CLI版との対応)
| やること | XAMPP for Linux | Docker |
|---|---|---|
| 起動 | sudo /opt/lampp/lampp start |
docker compose up -d |
| 停止 | sudo /opt/lampp/lampp stop |
docker compose down |
| 状態確認 | lampp status |
docker compose ps |
| ログ | ログファイル | docker compose logs -f |
| SQL手動実行 | mysql -u root |
docker compose exec db mysql -uroot myportal |
| DB初期化 | phpMyAdmin |
init.sql が自動実行 |
トラブル時
| 症状 | 対処 |
|---|---|
最初の数秒 接続失敗
|
DB初期化中。数秒待つ。続くなら docker compose logs db
|
init.sql が反映されない |
DB初回作成時のみ実行。作り直しは docker compose down -v してから up
|
| ポート8080使用中 |
"8080:80" を "8090:80" 等に変更 |
localhost で接続失敗 |
db.php の接続先を db にしたか確認(Docker版の肝) |
まとめ:3パターンの違いは実質3点だけ
| サーバ起動 | DB作成 | 接続先ホスト | |
|---|---|---|---|
| XAMPP GUI | Control Panelのボタン | phpMyAdmin | localhost |
| XAMPP CLI Linux |
lampp コマンド |
mysql コマンド |
localhost |
| Docker | docker compose up |
init.sql 自動実行 |
db(サービス名) |
アプリのPHPコードは共通。環境が変わっても「起動方法・DBの作り方・接続ホスト名」を読み替えれば、同じアプリがそのまま動きます。