Dockerを使ってMac上にLAMP(Linux + Apache + MySQL + PHP)環境を構築する方法を解説します。
Dockerのインストールがまだの方はこちらをご覧ください。
- Mac min (M1, 2020)
- macOS Sonoma 14.2.1
- Docker Desktop 4.27.1
- PHP 8.3
- Apache 2.4.57
- MySQL 8.3
- phpMyAdmin 最新版
Docker Composeを使う
今回は、複数のコンテナをまとめて管理したいのでDocker Composeというツールを使います。Dockerがインストールされていればすぐに使うことができます。
Docker Composeを使うには、compose.yaml
という名前のファイルにあらかじめ設定を記述しておきます。
ファイル構成
以下のような構成でディレクトリとファイルを作成します。
php83-dev/
├── compose.yaml
├── html/
│ └── index.php
├── mysql/
│ └── my.cnf
└── php/
├── Dockerfile
└── php.ini
php83-dev | この開発環境のルートフォルダです。名前は自由につけてください。 |
---|---|
compose.yaml | Docker Composeの設定ファイルです。 |
html | ウェブサーバのルートディレクトリです。ここにPHPのスクリプトファイルを入れます。中にはindex.php を配置しています。 |
mysql | MySQLのコンテナに関連するファイルを入れておくフォルダです。MySQLの設定ファイルmy.cnf を入れています。 |
php | PHPのコンテナに関連するファイルを入れておくフォルダです。Dockerイメージの設計図であるDockerfile とPHPの設定ファイルphp.ini を入れています。 |
各種ファイルの作成
compose.yaml
compose.yaml
の内容は以下のようになります。YAML形式で記述します。
services:
php:
build: ./php/
volumes:
- ./php/php.ini:/usr/local/etc/php/php.ini
- ./html:/var/www/html
ports:
- '8080:80'
restart: always
mysql:
image: mysql:8.3
volumes:
- ./mysql/my.cnf:/etc/my.cnf
- ./mysql/data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
ports:
- '3307:3306'
environment:
- MYSQL_ROOT_PASSWORD=************
# - MYSQL_DATABASE=dbname
# - MYSQL_USER=user
# - MYSQL_PASSWORD=************
restart: always
phpmyadmin:
image: phpmyadmin:latest
ports:
- '8090:80'
environment:
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=************
restart: always
ファイル名
Composeファイルは以下のどの名前でもOKですが、公式ではcompose.yaml
が推奨されています。
- compose.yaml (推奨)
- compose.yml
- docker-compose.yaml
- docker-compose.yml
昔はdocker-compose.yml
が標準だったので、いまだにこのファイル名が使われることが多いですね。でも複数のファイルが存在する場合はcompose.yaml
が優先されるそうです。知識、アップデートしてこー。
services:
services:
の下層に作成したいサービス(コンテナ)を記述します。
services:
php: #phpという名前でサービスを定義
...
mysql: #mysqlという名前でサービスを定義
...
phpmyadmin: #phpmyadminという名前でサービスを定義
...
サービス名は自由に決めてOKです。ここでは「php」「mysql」「phpmyadmin」としました。
build:
Dockerイメージの設計図であるDockerfile
の場所を指定します。
以下のように記述すると./php/Dockerfile
を指定したことになります。
build: ./php/
Dockerfile
のデフォルトのファイル名を使わない場合は次のように記述します。ファイル名がphp.Dockerfile
の場合の例です。
build: ./php/php.Dockerfile
次のように書くこともできます。
build:
context: ./php/
dockerfile: php.Dockerfile
volumes:
ホストとコンテナのディレクトリ・ファイルを紐付けます。
コンテナ内に作成されたデータは、コンテナを削除したり更新したりすると消えてしまいます。volumes:
の設定をしておくことで、コンテナ内のデータはホストのファイルシステムに保存されるので、データの永続化が可能になります。
volumes:
- <ホストのファイル・ディレクトリ>:<コンテナのファイル・ディレクトリ>
...
今回は以下のファイル・ディレクトリを設定しています。
PHPの設定ファイル | ./php/php.ini:/usr/local/etc/php/php.ini |
---|---|
Apacheのドキュメントルート | ./html:/var/www/html |
MySQLの設定ファイル | ./mysql/my.cnf:/etc/my.cnf |
MySQLのデータディレクトリ | ./mysql/data:/var/lib/mysql |
MySQLのDB初期化ディレクトリ | ./mysql/init:/docker-entrypoint-initdb.d |
他にも、Apacheのログディレクトリ(/var/log/apache2
)とか、MySQLのログディレクトリ(/var/log
)とか、phpMyAdminの設定ファイル(/var/www/html/config.inc.php
)など、必要に応じて設定してもいいかもしれません。
ports:
ホストとコンテナのポート番号を紐付けます。
ports:
- '<ホストのポート番号>:<コンテナのポート番号>'
...
今回は以下のようにポートの設定をしています。
PHPを実行するApacheのポート | '8080:80' |
---|---|
MySQLのポート | '3307:3306' |
phpMyAdminを実行するApacheのポート | '8090:80' |
ここではホストとコンテナで異なるポート番号を紐付けていますが、ホスト側でシステムポートを使っていないならば'80:80'
のように同じポート番号を紐付けることも可能です。
macOSで特定のポートが使われているか確認するにはコマンドsudo lsof -P -i:<ポート>
を実行してください。何か表示されたら使用済みということです。
% sudo lsof -P -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 704 user 5u IPv6 0x40d655bb0b855017 0t0 TCP *:80 (LISTEN)
httpd 821 user 5u IPv6 0x40d655bb0b855017 0t0 TCP *:80 (LISTEN)
httpd 822 user 5u IPv6 0x40d655bb0b855017 0t0 TCP *:80 (LISTEN)
httpd 823 user 5u IPv6 0x40d655bb0b855017 0t0 TCP *:80 (LISTEN)
httpd 824 user 5u IPv6 0x40d655bb0b855017 0t0 TCP *:80 (LISTEN)
httpd 825 user 5u IPv6 0x40d655bb0b855017 0t0 TCP *:80 (LISTEN)
restart:
コンテナの再起動ポリシーの設定です。restart: always
とすると、Dockerを起動したらコンテナが自動起動します。
image:
コンテナ実行の元となるイメージを指定します。サービスmysql
とphpmyadmin
はこの方法でコンテナを起動します。
image: <イメージ名>:<タグ>
イメージはDocker Hubで検索できます。どんなタグが利用できるかもこちらで確認できます。タグでバージョンなどを指定することができます。
environment:
コンテナに環境変数を設定します。
今回は以下の環境変数を設定しました。
mysqlの環境変数 | ||
---|---|---|
MySQLのrootのパスワード | 必須 | MYSQL_ROOT_PASSWORD=************ |
イメージの起動時に作成するDBの名前 | オプション | MYSQL_DATABASE=dbname |
上記DBに対応するユーザ | オプション | MYSQL_USER=user |
上記ユーザのパスワード | オプション | MYSQL_PASSWORD=************ |
phpmyadminの環境変数 | ||
---|---|---|
phpMyAdminの接続先ホスト名 | compose.yamlで設定したMySQLのサービス名を指定 | PMA_HOST=mysql |
phpMyAdminのログインユーザ名 | MySQLのユーザ名を指定 | PMA_USER=root |
phpMyAdminのログインパスワード | 上記ユーザのパスワードを指定 | PMA_PASSWORD=************ |
php/Dockerfile
PHPのイメージを作成するためのDockerfile
の内容は以下のようになります。
FROM php:8.3-apache
RUN apt update \
&& apt install -y libonig-dev \
&& docker-php-ext-install pdo_mysql mysqli mbstring
FROM
FROM
でベースイメージを指定します。
FROM <イメージ名>:<タグ>
ここではDocker HubにあるPHPの公式イメージを使っています。タグは8.3-apache
で、PHP 8.3系の最新バージョンのApacheモジュール版を意味しています。
RUN
RUN
でイメージを構築するときに実行するシェルコマンドを指定します。
まず、apt update
でパッケージリストの更新をします。言い忘れてましたが、PHPの公式イメージを使う場合、OSはDebianです。えーと、正確に言うとDebianがインストールされているわけではないのですが、Debianのapt
コマンドが使えます。
次に、apt install -y libonig-dev
でOnigurumaというライブラリをインストールします。mbstringが必要としています。
最後に、docker-php-ext-install ...
でPHPの拡張モジュールをインストールします。ここではpdo_mysql
, mysqli
, mbstring
をインストールしました。
他にもインストールしたい拡張モジュールがあれば追加してください。このとき、モジュールが依存するライブラリがあるならば先にインストールしておく必要があるので注意してちょんまげ。
php/php.ini
PHPの設定ファイルphp.ini
を作ります。
[PHP]
engine = On
memory_limit = 128M
error_reporting = E_ALL
display_errors = On
display_startup_errors = On
log_errors = On
post_max_size = 64M
default_charset = "UTF-8"
upload_max_filesize = 64M
[Date]
date.timezone = Asia/Tokyo
[MySQLi]
mysqli.default_port = 3307
[mbstring]
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
もっとちゃんとした設定ファイルを作りたいならば、コンテナを起動したあとに設定ファイルのサンプルをコピーしましょう。
php.iniのサンプル(開発用)の場所 | /usr/local/etc/php/php.ini-development |
---|---|
php.iniのサンプル(本番用)の場所 | /usr/local/etc/php/php.ini-production |
コンテナからホストへファイルをコピーするにはdocker cp
コマンドを使います。
% docker cp <コンテナ名またはID>:<パス> <ホストのパス>
起動中のコンテナ名およびIDを確認するコマンドはdocker ps
です。
#コンテナ名を確認
% docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
************ php83-dev-php ******* ******* ****** ***** php83-dev-php-1
************ mysql:8.3 ******* ******* ****** ***** php83-dev-mysql-1
************ phpmyadmin:latest ******* ******* ****** ***** php83-dev-phpmyadmin-1
#サンプルをホストにコピー
% docker cp php83-dev-php-1:/usr/local/etc/php/php.ini-development ./php/
コンテナを起動してからでないとできませんからね!ちゃんと言ったからね!
mysql/my.cnf
MySQLの設定ファイルmy.cnf
を作ります。
[mysqld]
user = mysql
socket = /var/run/mysqld/mysqld.sock
pid-file = /var/run/mysqld/mysqld.pid
datadir = /var/lib/mysql
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
skip-name-resolve
host-cache-size = 0
secure-file-priv = /var/lib/mysql-files
default-time-zone = Asia/Tokyo
[client]
socket = /var/run/mysqld/mysqld.sock
default-character-set = utf8mb4
!includedir /etc/mysql/conf.d/
html/index.php
index.php
を作ります。phpinfo()を出力するだけの簡単なスクリプトです。
<?php
phpinfo();
コンテナの起動
さあ、いよいよコンテナを起動します。以下のコマンドを実行してください。
% cd php83-dev #プロジェクトのディレクトリに移動
% docker compose up -d #コンテナ起動
無事コンテナが起動しましたか?おめでとうございます。
以下のエラーが出た場合はDockerデーモンが起動していないので、Dockerを立ち上げてください。
% docker compose up -d
Cannot connect to the Docker daemon at unix:///Users/user/.docker/run/docker.sock. Is the docker daemon running?
動作確認
コンテナが起動したら動作確認をしましょう。
ウェブブラウザで http://localhost:8080/ にアクセスしたらphpinfo()が表示されるはずです。いえーい。
http://localhost:8090/ にアクセスしたらphpMyAdminが表示されたでしょうか。いえーい。
でわでわ
コメント