Dockerを使って簡単にPHPの開発環境(Apache + PHP + MySQL)を構築する方法
2024年 4月17日 Posted 野々瀨(フロントエンドエンジニア)
今回は仮想環境を構築できるDockerを使用して、PHPの開発環境(Apache + PHP + MySQL)を構築する方法をご紹介しようと思います。
※ 本記事は、2023年10月現在の内容です。ご覧になっている時期によっては内容が古いことがありますので、ご了承ください。
Dockerとは
Dockerとは、軽量で高速に動作する、ホストOS上で複数の仮想環境を構築できるプラットフォームです。仮想マシンと違いゲストOSが不要で、ホストOSのシステムを使って、コンテナという単位で様々なアプリケーションを独立して動作させることができます。同一アプリケーションでも独立して動作させることができるので、プロジェクトごとにバージョンの違うアプリケーションを扱うことができます。また、コンテナという単位で隔離することで、他の人にも同じ環境を構築することができます。

一方デメリットもあり、コンテナはホストOSで動作するので、アプリケーションが対応するOSとホストOSが異なるものでは動作させることはできません。
Docker Desktopとは
Docker Desktopとは、WindowsやMacでDockerを簡単に構築・管理することができるアプリケーションです。Docker自体はLinux上でしか動作に対応していませんが、Docker Desktopを使用することでLinux以外でもDockerを動作させることができます。なお、Docker DesktopはDocker本体とDocker Composeを含みますので、コマンドラインからも実行することができます。
有料化
Docker Desktopは完全に無料で利用することができましたが、2021年9月ごろから次の条件で有料化されました。
- 大企業 (従業員数250人以上、または年間収益1,000万ドル以上) での商用利用
 
個人利用もしくは上記の条件を満たさない企業、教育機関、非商用のオープンソースプロジェクトでは、引き続き無料で利用することができます。
動作環境(使用条件)
Linux、Windows、Macに対応しています。Windowsの場合は、次の条件を満たしている必要があります。
- WSL(Windows Subsystem for Linux)1.1.3.0以降
 - Windows 10 64bit(Home、Pro、Enterprise、Education)またはWindows 11 64bit(Home、Pro、Enterprise、Education)
 - CPU:SLAT(Second Level Address Translation)機能をサポートした64bitプロセッサ
 - メモリ:4GB以上
 
Windowsのコンテナ(アプリケーション)を実行させる場合は、ProまたはEnterpriseのエディションである必要があります。また、バージョン21H2以上が必要です。
本記事では、Windowsを対象としてご紹介していきます。
WSL(Windows Subsystem for Linux)の有効化
WSLはWindows Subsystem for Linuxの略称で、Windows上でLinux環境を実行できるようにするシステムです。Dockerを利用するには、このWSLを有効にしている必要があります。
WSLはバージョンが1のものと2のものがありますが、バージョン1では手動でLinuxディストリビューションのインストールが必要で、バージョン2では自動的にインストールされます。ここではバージョン2で説明を行います。
WSLを有効にする方法は主に次の3つがあります。
- 「Windows の機能の有効化または無効化」画面から行う方法
 - コマンドから行う方法
 - Microsoft Storeから行う方法
 
どの方法でも一緒ですが、ここでは「Windows の機能の有効化または無効化」画面から行う方法で説明しようと思います。
「Windows の機能の有効化または無効化」画面を開くにはいくつか方法がありますが、「設定」画面を開き、検索欄に「Windows の機能の有効化または無効化」と入力すると、同名の結果が表示されますので、それを押します。「Windows の機能の有効化または無効化」画面が開いたら、Windows 11の場合は「Linux 用 Windows サブシステム」、Windows 10の場合は「Windows Subsystem for Linux」と、「仮想マシンプラットフォーム」という2つの項目があるのでチェックを入れ、「OK」ボタンを押します。

しばらくすると完了しますので、パソコンを再起動します。再起動後、Ubuntuがインストールされていればユーザー名とパスワードの設定を求められるので、入力すれば有効化が完了となります。もしUbuntuがインストールされていなければ、Microsoft Storeからインストールすることができます。

もしお好みのLinuxディストリビューションをインストールしたい場合は、Microsoft Storeやコマンドなどからインストールすることができます。
Docker Desktopのインストールおよび起動
次のページへアクセスし、「Docker Desktop for Windows」ボタンを押して、インストーラーをダウンロードします。
https://docs.docker.com/desktop/install/windows-install/

ダウンロードしたインストーラーを起動します。

そのまま「Ok」を押します。


しばらくするとインストールが完了し、「Close」を押します。この時パソコンの再起動を求められる場合があります。その場合は「Close and restart」ボタンを押すことで、自動的にパソコンが再起動されます。

デスクトップに作成されたショートカット「Docker Desktop」を起動します。(パソコンを再起動した場合は自動的にDocker Desktopが起動します。)

初回起動では、サービスに同意する必要がありますので、内容を読んで「Accept」ボタンを押します。

アカウントを持っている場合は「Sign in」を押してサインインし、持っていない場合は「Sign up」を押して、アカウントを作成します。ただし、無料利用ならアカウントなしで利用できますので、その際は「Continue without signing in」を押します。

これでインストールから初回起動までが完了です。

なお、コマンドラインからもインストールされたかを確認することができます。docker -vでDocker本体のバージョン、docker-compose -vでDocker Composeのバージョンをそれぞれ確認することができます。

Docker Desktopで開発環境を構築
Docker Desktopで次の3つの環境を構築します。
- Apache + PHP
 - MySQL
 - phpMyAdmin
 
phpMyAdminについてはデータベースを簡単に扱えるようにするために用意しているので、必要なければ構築しなくても問題ありません。
ApacheとPHPのイメージをダウンロード
Docker Desktopのタイトルバー中央にある検索エリアを押すか、キーボードのCtrl + Kキーを押します。

検索入力欄に「php」と入力し、しばらくすると結果が表示されますので、その中から「php」項目を探します。Tagのプルダウンから「apache」を選択し、「Pull」ボタンを押してイメージのダウンロードを開始します。

イメージのダウンロードが完了すると、結果に新たに「php:apache」と追加されます。

Escキーを押して検索画面を閉じます。左のメニューのアイコンから「Images」を押します。

先ほどダウンロードしたイメージが表示されていることを確認します。

MySQLのイメージをダウンロード
Docker Desktopのタイトルバー中央にある検索エリアを押すか、キーボードのCtrl + Kキーを押します。検索入力欄に「mysql」と入力し、しばらくすると結果が表示されますので、その中から「mysql」項目を探します。「Pull」ボタンを押してイメージのダウンロードを開始します。

イメージのダウンロードが完了すると、結果に新たに「mysql:latest」と追加されます。

左のメニューのアイコンから「Images」を押します。先ほどダウンロードしたイメージが表示されていることを確認します。

phpMyAdminのイメージをダウンロード
Docker Desktopのタイトルバー中央にある検索エリアを押すか、キーボードのCtrl + Kキーを押します。検索入力欄に「phpmyadmin」と入力し、しばらくすると結果が表示されますので、その中から「phpmyadmin」項目を探します。「Pull」ボタンを押してイメージのダウンロードを開始します。

イメージのダウンロードが完了すると、結果に新たに「phpmyadmin:latest」と追加されます。

左のメニューのアイコンから「Images」を押します。先ほどダウンロードしたイメージが表示されていることを確認します。

ファイル/ディレクトリの準備
任意のディレクトリに次のファイルとディレクトリを用意します。
├─mysql
│  ├─conf
│  │  └─my.cnf
│  └─data
├─php
│  └─php.ini
└─public
| ファイル/ディレクトリ | 説明 | 
|---|---|
| mysql/conf/my.cnf | MySQLの設定ファイル。ファイル名は任意で指定して問題ない。 | 
| mysql/conf/data | データベースのデータを永続的に保存するためのディレクトリ。 | 
| php/php.ini | PHPの設定ファイル。 | 
| public | Webサーバの公開領域のルートディレクトリ。 | 
mysql/conf/my.cnfファイルの準備
mysql/conf/my.cnfファイルを作成します。MySQLで設定を変更したい項目を記述します。ここでは次のように記述しています。
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
[mysql]
default-character-set=utf8mb4
| グループ | 変数名 | 説明 | 
|---|---|---|
| mysqld | character-set-server | サーバ側で関係する文字コード。 | 
| mysqld | collation-server | クライアント側から受け取った文字を変換する文字コード。 | 
| mysql | default-character-set | クライアント側で関係する文字コード。 | 
my.cnfファイルはパーミッションの設定を行う必要があります。しかしWindowsではパーミッションの設定は行えないため、ファイルのプロパティを開き「読み取り専用」にチェックを入れます。

php/php.iniファイルの準備
php/php.iniファイルを作成します。PHPで設定を変更したい項目を記述します。ここでは次のように記述しています。
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.language = "Japanese"
extension=mbstring
extension=pdo_mysql
max_execution_time = 120
memory_limit = 256M
post_max_size = 100M
upload_max_filesize = 100M
| グループ | 変数名 | 説明 | 
|---|---|---|
| Date | date.timezone | スクリプト上で使用される時間のタイムゾーン。 | 
| mbstring | mbstring.language | mbstringで初期で使用する言語。 | 
| extension | 使用する拡張モジュールの有効化。 | |
| max_execution_time | スクリプトの実行時間。 | |
| memory_limit | メモリの容量。 | |
| post_max_size | POSTデータの最大容量。 | |
| upload_max_filesize | アップロード可能な最大ファイル容量。 | 
インデックスページの準備
publicディレクトリに「index.php」という名前のファイルを作成します。index.phpを編集し、次のコードを記述します。
<?php phpinfo(); ?>
ネットワークの作成
Dockerのネットワークは、初期で「bridge」という名前のネットワークが用意されていて、コンテナーを作成した際はこの「bridge」ネットワークが割り当てられます。しかし「bridge」ネットワークは何故かコンテナー間で通信することができません。
そこで新しくネットワークを作成し、その作成したネットワークを通信するコンテナーに割り当てることで、コンテナー間で通信することが可能になります。ただし、Docker DesktopのGUI上ではネットワークを作成することができませんので、CLIで行います。
コマンドラインツールを起動し、docker network create ネットワーク名コマンドを入力・実行します。ネットワーク名は任意に設定できます。
$ docker network create network_test
sz123ksl743819eqx1mku2h8102se67ss42470g9051da91f636e388a321fc34d
docker network lsコマンドを入力・実行し、作成されたことを確認します。
$ docker network ls
NETWORK ID     NAME           DRIVER    SCOPE
ab01ff478cbe   bridge         bridge    local
3c6bc89f0908   host           host      local
ca810aec9276   network_test   bridge    local
ネットワークとコンテナーの紐付けは後ほど行います。
コンテナーの作成と起動
MySQLのコンテナーを作成・起動
MySQLのイメージの"Actions"列にある「Run」ボタンを押します。

コンテナ―の作成画面が表示されますので、「Optional settings」を押してオプション設定領域を表示します。「Container name」、「Ports」、「Volumes」、「Environment variables」を設定します。「Volumes」と「Environment variables」は、「+」ボタンを押すことで入力領域を追加することができます。

Container name
コンテナーの名称を指定します。半角英数字(英字は大文字小文字どちらも可能)、半角アンダースコア、半角ハイフン、半角ドットを使用することができます。
Ports
ホスト側で使用するポート番号を指定します。「0」を指定すると、起動時に自動的に割り当てられます。
Volumes
ホスト側とDocker側のデータを繋げるためのものです。コンテナーは変更されたデータは停止するとリセットされますが、Volumeで紐付けされた部分は、ホスト側とDocker側でデータが同期されるので、永続的にデータを保持することができます。
| ホスト側パス | コンテナー側パス | 
|---|---|
| C:/docker/mysql/conf/my.cnf | /etc/mysql/conf.d/my.cnf | 
| C:/docker/mysql/data | /var/lib/mysql | 
Environment
環境変数を設定します。
| 変数名 | 設定値(例) | 説明 | 
|---|---|---|
| MYSQL_ROOT_PASSWORD | root | ユーザー「root」のパスワード。 | 
| MYSQL_DATABASE | testdb | 初期で作成するデータベース名。 | 
| MYSQL_USER | testuser | 初期で作成するアカウントのユーザー名。MYSQL_DATABASEのユーザーとして割り当てられる。 | 
| MYSQL_PASSWORD | 1234567890 | 「MYSQL_USER」のパスワード。 | 
| TZ | Asia/Tokyo | タイムゾーン。 | 
しばらくすると起動が完了します。

Apache + PHPのコンテナーを作成・起動
PHPのイメージの"Actions"列にある「Run」ボタンを押します。

コンテナ―の作成画面が表示されますので、「Optional settings」を押してオプション設定領域を表示します。「Container name」、「Ports」、「Volumes」を設定します。

Container name
コンテナーの名称を指定します。
Ports
ホスト側で使用するポート番号を指定します。「0」を指定すると、起動時に自動的に割り当てられます。
Volumes
ホスト側とDocker側のデータを繋げるためのものです。コンテナーは変更されたデータは停止するとリセットされますが、Volumeで紐付けされた部分は、ホスト側とDocker側でデータが同期されるので、永続的にデータを保持することができます。
| ホスト側パス | コンテナー側パス | 
|---|---|
| C:/docker/php/php.ini | /usr/local/etc/php/php.ini | 
| C:/docker/public | /var/www/html | 
しばらくすると起動が完了します。

PHPの拡張モジュールのインストール
初期ではデータベースの拡張モジュールが入っていないので、インストールします。「Exec」タブを押します。

次のコマンドを入力し実行します。
apt-get update && docker-php-ext-install pdo pdo_mysql mysqli

しばらくするとインストールが完了します。右上にある「Restart」ボタンを押してコンテナーを再起動します。

phpMyAdminのコンテナーを作成・起動
phpMyAdminのイメージの"Actions"列にある「Run」ボタンを押します。

コンテナ―の作成画面が表示されますので、「Optional settings」を押してオプション設定領域を表示します。「Container name」、「Ports」、「Environment」を設定します。

Container name
コンテナーの名称を指定します。
Ports
ホスト側で使用するポート番号を指定します。「0」を指定すると、起動時に自動的に割り当てられます。
Environment
環境変数を設定します。
| 変数名 | 設定値(例) | 説明 | 
|---|---|---|
| PMA_HOST | mysql_test | 接続するMySQLのホスト名。Dockerではコンテナー名を指定する。 | 
| PMA_PORT | 3306 | 接続するMySQLのポート番号。Dockerではコンテナーのポート番号を指定する。 | 
しばらくすると起動が完了します。

ネットワークの割り当て
docker network connect ネットワーク名 コンテナー名コマンドを入力・実行し、コンテナーに作成したネットワークを割り当てます。
$ docker network connect network_test php_test
$ docker network connect network_test mysql_test
$ docker network connect network_test pma_test
ブラウザで表示を確認
いよいよブラウザで表示を確認してみます。
Apache + PHPの確認
Docker Desktopの画面からContainers画面を開き、Apache + PHPのPort(s)列のリンクを押します。

既定ブラウザが起動し、index.phpの内容が表示されます。

phpMyAdminの確認
Containers画面からphpMyAdminのPort(s)列のリンクを押します。

既定ブラウザが起動し、ログイン画面が表示されます。MySQLのコンテナー作成時に、環境変数で設定した初期アカウントのユーザー名とパスワードを入力し、「ログイン」ボタンを押します。

ログインが成功すれば確認完了です。MySQLのコンテナー作成時に、環境変数で設定した初期データベースも確認します。

PHPからデータベースにアクセスしてみる
public/index.phpファイルを開き、次のコードに置き換えます。
<?php
const HOST_NAME = 'mysql_test';
const HOST_PORT = '3306';
const DB_NAME   = 'testdb';
const USER_NAME = 'testuser';
const PASSWORD  = '1234567890';
$db_settings = [
	'host='.HOST_NAME,
	'port='.HOST_PORT,
	'dbname='.DB_NAME,
	'charset=utf8'
];
try {
	$db = new PDO('mysql:'.implode(';', $db_settings), USER_NAME, PASSWORD);
	echo '接続成功';
} catch (PDOException $e) {
	echo '接続失敗:'.$e->getMessage();
}
?>
ブラウザでアクセスし、「接続成功」と表示されれば、Apache + PHPのコンテナーからMySQLのコンテナーへアクセスできることを確認することができます。
Docker Composeで開発環境を構築
Dockerには「Docker Compose」という、複数のイメージのビルドや各コンテナーの起動などを、簡単に行えるようにするツールが同梱されています。Docker Desktopの画面上ではなく、Docker Composeを使用した環境の構築方法をご紹介しようと思います。
Dockerfileを用意
phpディレクトリに「Dockerfile」というファイル名で作成します。
├─mysql
│  ├─conf
│  │  └─my.cnf
│  └─data
├─php
│  ├─php.ini
│  └─Dockerfile
└─public
作成したDockerfileファイルを開き、次の内容を記述します。
# インストールするイメージ
FROM php:apache
# 拡張モジュールをインストール
RUN apt-get update && apt-get install -y \
  && docker-php-ext-install pdo pdo_mysql mysqli
書き方についてはここでは説明しません。詳しくは次のページをご覧ください。
docker-compose.ymlを用意
phpなどのディレクトリの同階層に「docker-compose.yml」というファイル名で作成します。
├─mysql
│  ├─conf
│  │  └─my.cnf
│  └─data
├─php
│  ├─php.ini
│  └─Dockerfile
├─public
└─docker-compose.yml
docker-compose.ymlファイルを開き、次の内容を記述します。
version: '3.0'
services:
  # Webサーバー
  web:
    build: ./php/
    container_name: php_test
    ports:
      - "0:80"
    volumes:
      - ./php/php.ini:/usr/local/etc/php/php.ini
      - ./public:/var/www/html
    depends_on:
      - db
    networks:
      - network_test
  # データベース
  db:
    image: mysql:latest
    container_name: mysql_test
    ports:
      - "3306:3306"
    volumes:
      - ./mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./mysql/data:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=testdb
      - MYSQL_USER=testuser
      - MYSQL_PASSWORD=1234567890
      - TZ=Asia/Tokyo
    networks:
      - network_test
  # phpMyAdmin
  pma:
    image: phpmyadmin:latest
    container_name: pma_test
    ports:
      - "0:80"
    environment:
      - PMA_HOST=mysql_test
      - PMA_PORT=3306
    depends_on:
      - db
    networks:
      - network_test
# ネットワーク
networks:
  network_test:
    driver: bridge
書き方についてはここでは説明しません。詳しくは次のページをご覧ください。
セットアップ開始
コマンドラインツールを起動し、docker-compose.ymlのあるディレクトリへ移動します。次のコマンドを入力し実行します。
docker-compose up -d
全てのコンテナーが「Started」となっていれば完了です。

Docker Desktopの画面上で、Docker Composeで作成したイメージやコンテナーを確認することができます。

Visual Studio CodeでDockerを使う
Visual Studio CodeにはDockerの拡張機能があります。Visual Studio Code上で構築や管理、起動などの操作を行うことができます。
インストール方法は簡単で、まずVisual Studio Codeを起動し、拡張機能を開きます。開いたら検索入力欄に「docker」を入力します。検索結果からMicrosoftの「Docker」にある「インストール」ボタンを押します。

インストールが完了すると、サイドバーにDockerアイコンが追加されます。サイドバーにあるDockerアイコンを押すと、パネルが表示されます。

