1. ゴールと非対象
対象読者
- Docker / WSLに慣れていないPHP初学者〜初級者
- Windows 11で、まず1つ動く開発環境を作りたい人
この記事で到達する状態
http://localhost:8080でPHPページが表示できる- PHPコンテナからPostgreSQLへPDO接続できる
非対象
- PHPの複数バージョン切り替え(mise / asdfなど)
- 本番インフラ構築
- KubernetesやWebサーバーの高度なチューニング
先に分岐
- WSL2未導入: 3章から
- Docker Desktop未導入: 4章から
- WSL2とDocker Desktopが導入済み: 5章から
2. 前提確認
まずは、必要な前提だけ先に確認します。ここを先に済ませると後の手順で止まりにくくなります。
2-1. WSLとDockerの状態を確認
PowerShellで実行します。
wsl --status
wsl --list --verbose
docker version
docker compose version
wsl コマンドがエラーになる、または未導入の場合は3章へ進んでください。
確認ポイント:
wsl --list --verboseのVERSIONが2docker versionがエラーにならないdocker compose versionが表示される
2-2. 仮想化の有効化を確認
- タスクマネージャー -> パフォーマンス -> CPU ->
仮想化: 有効を確認
3. WSL2セットアップ
この章はWSL2未導入の人向けです。導入済みなら4章へ進んでください。
3-1. WSL2を導入
PowerShell(管理者)で実行:
wsl --install -d Ubuntu-24.04
実行後にWindowsを再起動し、Ubuntuを初回起動してユーザー名/パスワードを設定します。
3-2. Ubuntuの起動を確認
Ubuntu(WSL)で実行:
pwd
wslpath -m ~
ホームディレクトリのパスが表示されればOKです。
3-3. VS CodeからWSLを開く(必須)
code .
code コマンドが使えない場合は、VS CodeのRemote - WSL拡張を入れてから再実行してください。
3-4. ファイルの作り方
この後の章で作る docker-compose.yml や Dockerfile は、code . で開いたVS Code上で作成してください。
code(基本):- 左側のエクスプローラーで「新しいファイル」を作成
- 本文のサンプルを貼り付けて保存
nano(codeが使えないときの代替):nano ファイル名で開く- 貼り付け後、
Ctrl + O-> Enter で保存 Ctrl + Xで終了
例:
nano docker-compose.yml
注意:
/mnt/c/...配下で開発するとI/Oが遅くなりやすいので、~/projects配下を使います。
4. Docker DesktopとWSL連携を有効化する
4-1. Docker Desktopを導入
未導入の場合は、Docker Desktop公式手順でインストールします。
4-2. WSL Integrationを有効化
Docker Desktopで次を設定します。
Settings->Resources->WSL IntegrationUbuntuをONApply & Restart

4-3. WSLターミナルから確認
docker version
docker compose version
どちらも表示されれば次へ進めます。
5. docker-compose.yml を作る
この章で、後続のPDO接続確認に必要な pdo_pgsql 拡張まで有効化します。
5-1. 作業ディレクトリを作成して移動
mkdir -p ~/projects/php-beginner-app
cd ~/projects/php-beginner-app
mkdir -p app docker/php
3章でホームディレクトリを開いたままの場合は、ここで code . を実行して ~/projects/php-beginner-app を開き直してください。
5-2. docker-compose.yml を作成
~/projects/php-beginner-app/docker-compose.yml
services:
app:
build:
context: .
dockerfile: ./docker/php/Dockerfile
ports:
- "8080:80"
volumes:
- ./app:/var/www/html
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
environment:
POSTGRES_DB: app
POSTGRES_USER: app
POSTGRES_PASSWORD: apppass
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 5s
timeout: 3s
retries: 10
volumes:
pgdata:
5-3. Dockerfile を作成
~/projects/php-beginner-app/docker/php/Dockerfile
FROM php:8.5-apache
RUN apt-get update \
&& apt-get install -y --no-install-recommends libpq-dev \
&& docker-php-ext-install pdo pdo_pgsql \
&& rm -rf /var/lib/apt/lists/*
5-4. 構文確認と起動
docker compose config
docker compose up -d --build
docker compose ps
docker compose ps の STATUS が app: Up / db: Up (healthy) になっていれば次へ進めます。
5-5. pdo_pgsql の有効化確認
docker compose exec app php -m | grep -E '^(pdo|pdo_pgsql)$'
pdo と pdo_pgsql が表示されればOKです。

6. 最小PHPファイルを作る
6-1. index.php を作成
~/projects/php-beginner-app/app/index.php
<?php
declare(strict_types=1);
echo "<h1>PHP is working!</h1>";
echo "<p>PHP version: " . PHP_VERSION . "</p>";
6-2. PHPと表示を確認
docker compose exec app php -v
curl http://localhost:8080
ブラウザで http://localhost:8080 を開き、PHP is working! が表示されればOKです。

7. PostgreSQL接続を確認する
ここでは psql と PDO の両方で疎通確認します。
7-1. psql で接続確認
docker compose exec db psql -U app -d app -c "select version();"
docker compose exec db psql -U app -d app -c "select now();"
7-2. PDO接続確認用スクリプトを作成
~/projects/php-beginner-app/app/db-check.php
このファイルはローカル確認専用です。公開環境には置かないでください。./app は公開ディレクトリにマウントされるため、http://localhost:8080/db-check.php からもアクセスできます。
<?php
declare(strict_types=1);
$dsn = 'pgsql:host=db;port=5432;dbname=app';
$user = 'app';
$password = 'apppass';
try {
$pdo = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$stmt = $pdo->query('select now() as current_time');
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo "DB OK: {$row['current_time']}" . PHP_EOL;
} catch (PDOException $e) {
fwrite(STDERR, "DB NG: {$e->getMessage()}" . PHP_EOL);
exit(1);
}
7-3. PDO接続を実行
docker compose exec app php /var/www/html/db-check.php
DB OK: ... が表示されれば成功です。

注意:
host=localhostではなくhost=dbを使います(Composeのサービス名で接続するため)。/var/www/html/db-check.phpは、ホスト側の./app/db-check.phpに対応しています。
8. 日常運用コマンド
ここから先のコマンドは、~/projects/php-beginner-app で実行します。別ディレクトリにいる場合は、先に cd ~/projects/php-beginner-app を実行してください。
最初は次の4つだけ覚えれば進められます。
docker compose up -d
docker compose ps
docker compose logs -f app
docker compose down
DBデータも含めて初期化したいとき:
docker compose down -v
ポート競合を疑うとき(PowerShell):
netstat -ano | findstr :8080
netstat -ano | findstr :5432
9. よくあるエラーと復旧
9-1. docker compose が使えない
- 症状:
docker: command not foundなど - 原因: Docker Desktop未起動 / WSL Integration未設定
- 対処:
docker version
docker compose version
Docker Desktopを起動し、Settings -> Resources -> WSL Integration を再確認します。
9-2. pdo_pgsql が見つからない
- 症状:
could not find driver - 原因:
Dockerfileが反映されていない - 対処:
docker compose down
docker compose up -d --build
docker compose exec app php -m | grep -E '^(pdo|pdo_pgsql)$'
9-3. DB接続で Connection refused
- 症状: PDO接続失敗
- 原因: ホスト名ミス(
localhostを使っている) - 対処: DSNを
host=db;port=5432に修正して再実行
9-4. YAMLエラーで起動しない
- 症状:
yaml: line xx: ... - 原因: インデント崩れ
- 対処:
docker compose config
まず docker compose config が通る状態に直します。
9-5. ポート競合で起動しない
- 症状:
bind: address already in useでupに失敗する - 原因:
8080または5432を他プロセスが使用している - 対処:
netstat -ano | findstr :8080
netstat -ano | findstr :5432
競合がある場合は、docker-compose.yml 側のホストポートを変更するか、使用中プロセスを停止してから再実行します。
まとめ
この時点で、次の2点が通っていれば環境構築は完了です。
http://localhost:8080でPHPページが表示されるdocker compose exec app php /var/www/html/db-check.phpがDB OKになる
ここまでで、PHPとPostgreSQLのローカル開発環境の初期構築は完了です。