docker composeでPHPとMySQLの環境を
今、2025/05 時点の記事です。
Laravelの検証環境を作ろうとして、チャッピー(=ChatGPT)に聞きながら検証して作った作業手順および解説となります。例によって個人的の備忘録です。この手の作業に慣れていない人向けで、慣れた人には今さらなレベルですが、参考に出来る人はしてもらえればなーと。
今回導入するのはLaravel 12、 PHP 8.2、 MySQL 8.4 です。
なお、バージョン番号は融通が利きます。
OSは、クリーンインストールした Ubuntsu 24.04 を使って進めていきます。
昔、WSLを使ってWindows上にLinuxを動かすという記事を書いたんですが、あれの続きです。なので、WSLの記事として書いていますが、WSLである必要はないと思います。
- Ubuntsu 24.04 で検証しています
Docker Composeについて
Docker Compose とは、複数コンテナのアプリケーションを定義・共有するために役立つツール‥‥ということで、ようはPHPサーバーとMySQLのサーバー、2つの仮想サーバーをセット運用することでコマンド一つでシステムの開発環境を動作できるぞという代物です。
最初に共有しておくべき知識が2つあります。
-
docker-composeとdocker composeは別のもの
docker-composeはdocker-compose
というコマンドで、docker composeはdocker
コマンド内の1機能です。結論から言うとdocker composeの方が新しいので、必要なのはdockerだけです。本記事もこちらを取り扱います。 -
dockerのコンテナのOSは、dockerを起動しているOS(ホストOS)とは異なる
例えば、本記事では、WSLの上のUbuntsuでphp:7.4-apacheというコンテナを動かすのですが、このコンテナのOSはDebian系になるそうです。なのでUbuntsuの上で直にシステムを動かすのとは厳密には挙動が異なります。OSの機能をフル活用するタイプのプログラムとは相性が良くない事には注意が必要です。
Dockerの導入
とりあえず、Docker自体を動作させないことには始まりませんので入れていきます。
インストール
まずは、Dockerをインストールです。
sudo apt update
sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $USER
docker -v
Docker version 28.1.1, build 4eba377
docker -v
を実行して、バージョンが出てくれば完了。
ややこしいですが、一回やればOKなんで呪文として唱えましょう。
もちろん詠唱に意味はあります
下から解説します。
最後から2行目のapt install
がdockerのインストールコマンド本体です。
aptコマンドは自動的に/etc/apt/sources.list.d/
の下にあるlistファイルを参照してその内容を元にソフトを導入します。なので、そこにdocker.list
という名前でインストールに必要な情報を配置します。
echo文で出力しているのがその内容で、その中にはOSの情報が含まれています。
また、Dockerをインストールするときには、gpgファイルが必要です。これは、dockerが改竄されていないかどうかをチェックするためのファイルであり、curlコマンドでdocker公式から取得します。
gpgコマンドはテキストファイルをバイナリに変換するためのもので、変換したファイルを/etc/apt/keyrings
に配置します。(配置場所自体はどこでも良いものと思います)
最後のusermodコマンドは、dockerをsudoでなくても起動するよう権限を変更するためのものとのこと。(このコマンドは、反映には再起動が必要になります)
‥ですが、結局私のは上手くいかなかったようで結局この後もsudoしてます。
Deamonの起動
systemctlで確認・起動・終了ができます。起動していなければ起動しましょう。
# ステータス確認
sudo systemctl status docker
# 起動
sudo systemctl start docker
# 終了
sudo systemctl stop docker
systemctlが使えない環境ならserviceコマンド(sudo service docker start
等)です。
(あまり良くわからないので、この環境ではこっちなんだなーくらいで良いと思いますが)
MySQLとPHP動作環境の構築
Dockerが動作したので、いよいよコンテナを作りましょう。
まずは考えることの少ないDBサーバーを作ってdocker composeが動作することを確認、それからアプリサーバーとします。
1) プロジェクトフォルダを作成する
適当な名前を付けます。以後はこのフォルダ内で作業します。
その下にDocker関連ファイルを入れるためのフォルダとlaravelのソースを置くフォルダを作っておきます。
mkdir test-pj
cd test-pj
mkdir docker
mkdir src
2) docker-compose.ymlを作成する
docker-compose.ymlという名前のファイルを作ります。これは固定ファイル名です。
viなりお好きなテキストエディタで。
touch docker-compose.yml
vi docker-compose.yml
services:
db:
image: mysql:8.4
container_name: mysql84__tpj
restart: always
environment:
MYSQL_ROOT_PASSWORD: pass001
MYSQL_DATABASE: laradb
MYSQL_USER: laravel
MYSQL_PASSWORD: larapass
ports:
- "3306:3306"
volumes:
- ./docker/db_data:/var/lib/mysql
networks:
- laravel-net
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: pma__tpj
restart: always
ports:
- "8888:80"
environment:
PMA_HOST: db
PMA_PORT: 3306
UPLOAD_LIMIT: 100M
depends_on:
- db
networks:
- laravel-net
networks:
laravel-net:
サービスを2つ登録しています。(ここでは、サービス・コンテナ・サーバーほぼ同じものです)
ひとつは、db
サービスで、これをmysql:8.4
というイメージをベースに生成します。この8.4の部分がMySQLのバージョンなので、例えばmysql:5.7
とやれば5.7が導入できます。
もうひとつは、それを確認するためのphpMyAdminを動かすphpmyadmin
サービスです。これも専用のイメージが用意されています。
それぞれcontainer_nameを名付けます。test pjなので__tpj
等をくっつけてみました。必須ではないです。
より詳細な解説はこちら
[dbサービス]
environment部分、MYSQL_ROOT_PASSWORDがrootユーザのパスワードとなります。
加えて、1つのDBスキーマ、および、それにアクセスできるユーザを1人登録します。
この例の場合ですと、
root
/ pass001
と、 laravel
/ larapass
の2名でログインが可能、そして後者は、空のスキーマである laradb
にのみ、アクセスできます。
[pmaサービス]
ports部分は外(ホストOS)のポートを中(コンテナOS)のポートで書き換えるものになります。
この例では、ローカルマシンの8888ポートに接続することでコンテナ内の80で起動しているhttpサーバへつなぐことを意味します。
environmentでUPLOAD_LIMITを指定しましょう。デフォルトだとアップロード上限が2MBになります。
depend_onは、依存関係、主に起動順序を制御するためのものです。この書き方で、dbサービス → pmaサービスという順で起動するようになります。
その他
networksは文字通り、ネットワークを作ります。 統一されていれば名前は任意です
Volumeの記載について
上記の例では、こう設定しました。
volumes:
- ./docker/db_data:/var/lib/mysql
意味は、プロジェクトフォルダのdocker/db_dataフォルダをコンテナ内OSでの/var/lib/mysqlフォルダとして扱う、です。このように書くと、構築時にdb_dataフォルダが生成され、そこにMySQLの諸々ファイルが配置されます。
一方、こういう書き方もあります。
volumes:
- db_data:/var/lib/mysql
とした上で末尾に
volumes:
db_data:
と書く書き方です。
この書き方だとdocker側がボリュームを管理してくれるため、プロジェクトフォルダ内はすっきりします。
一方で、作業が終わってプロジェクトフォルダを削除してもデータが残り続け、別途消す必要が出てきますので、どちらが良いかはケースバイケースですね。
いちおう、出来たボリュームはdocker volume ls
などで確認することができます。
3) Dockerコンテナをビルドしてから実行
ymlが正しければ、ビルド実行は1コマンドです。
docker compose up -d --build
-d
はバックグラウンド実行を表し、--build
がビルド実行を意味します。
4) phpMyAdminで接続確認
http://127.0.0.1:8888/
に接続を試みます。
phpMyAdminの画面が表示され、root
/ pass001
でログインできれば、docker composeの導入には成功しています。
5) Dockerコンテナの終了
docker compose down
downで終了します。
6) Dockerfileを作成する
mySQLやphpMyAdminくらいであればymlの設定で十分に動くのですが、アプリサーバはそうはいかず、ビルド時のセットアップ時にいろいろ指示をする必要があります。そこで必要になるのがDockerfileです。
(ちなみに、このファイル名はこのあとymlで指定する為、何でもよいです)
touch docker/Dockerfile
vi docker/Dockerfile
FROM php:8.2-apache
# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
libzip-dev zip unzip git curl libonig-dev \
&& docker-php-ext-install pdo_mysql mbstring zip
# Composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
# Apacheのmod_rewriteを有効化
RUN a2enmod rewrite
# ドキュメントルート指定
RUN sed -i 's|DocumentRoot /var/www/html|DocumentRoot /var/www/html/public|g' /etc/apache2/sites-available/000-default.conf
# ワークフォルダの変更
WORKDIR /var/www/html
冒頭のFROM php:8.2-apache
が、PHP8.2とapacheのセットを表しています。
php:7.4-apache
のようなバージョン違いのほか、Nginxなどを使える指定もあります。
パッケージのインストール方法はOSに依存するわけですが、ここではコンテナ側のDebian系OSの書き方になります。ubuntuとはちょっと異なる感じになるなので、追加で必要なパッケージがあった場合は、ChatGPTにでも聞いてね。
ドキュメントルートについて
デフォルトの設定だとドキュメントルートは /var/www/html
こと src
です。しかしLaravelのドキュメントルートは /var/www/html/public
こと src/public
です。
そこで、apacheのconfに対して文字列置換をしています。Laravelを動かすだけならこれで良いのですが、もっと複雑なconfを書きたい場合は、別途confファイルを作ってそれと差し替えるという手もあります。
7) docker-compose.ymlの追記
docker-compose.ymlにapp
サービスを追加します。書くのはservices:
とdb
の間です。
# services:
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: laravel12__tpj
volumes:
- ./src:/var/www/html
ports:
- "8080:80"
depends_on:
- db
working_dir: /var/www/html
networks:
- laravel-net
# db:
# image: mysql:8.4
# :
先ほど作ったDockerfileを指定しておきます。
ports
は8080:80
なので、ローカルで8080ポートに接続すると、コンテナ内の80ポートに繋がる設定です。
8) Dockerコンテナ再ビルド実行
ビルド実行します。
docker compose up -d --build
9) laravel導入
9-1) laravel 新規PJ導入
空のlaravel 12をインストールする場合:
composerコマンドを使ってLaravelを入れるのですが、このコマンドはコンテナ内で実行する必要があります。コンテナ内でコマンドを打ちたい場合 docker compose exec [サービス名] [コマンド]
を使います。
つまり、インストールコマンドはこうなります。
docker compose exec app composer create-project laravel/laravel:^12.0 .
laravelフォルダ内にソースが出来たことを確認します。
9-2) laravel 既存PJ導入
すでに存在するlaravelを入れる場合:
git cloneなり手動配置なりで、コード一式をsrcフォルダに配置します。
続いて、composerで依存するパッケージのインストールとアプリキーの生成を行います。
この辺は通常通りといえばそうなのですが、各コマンドはコンテナ内で実行する必要があり、 docker compose exec [サービス名] [コマンド]
の構文で実行する必要があります。
docker compose exec app composer update
docker compose exec app composer install
docker compose exec app php artisan key:generate
10) .env書換え
src/.envを書き換えます。
Laravel 12はデフォルトSQLiteなので、mysqlに書き換えます。
コメントアウトを解除しつつ進めましょう。
DBのhostはDockerサービス名であるdb
を指定します。DB名・パスはymlで指定した通り。
:
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laradb
DB_USERNAME=root
DB_PASSWORD=pass001
:
11) 権限付与
Laravelでシステムが操作するフォルダのパーミッションを変更。
docker compose exec app chmod -R 777 storage bootstrap/cache
12) DBマイグレーション
Laravel 12の新規導入するとインストール時にマイグレーションが掛かりますが
あれはsqliteが対象となっていましたので、MySQLに切り替えた後、改めて実行する必要があります。
docker compose exec app php artisan migrate:fresh -v --seed
13) 接続確認完了
http://127.0.0.1:8080/
に接続を試みます。
laravelのトップ画面が出てくれば完了です。
お疲れ様でした。
Dockerコンテナの操作
# 起動
docker compose up -d
# 終了
docker compose down
# 確認
docker compose ps
-d
はバックグラウンド実行を意味します。
execでコンテナ内にコマンドが発行できるのは前述しましたが、bashを実行するとコンテナ内に入って作業できます。
docker compose exec app bash
最終的な構成:
プロジェクトフォルダ
test-pj
┣ docker-compose.yml docker compose用のyml
┣ docker ┳ Dockerfile アプリサーバーの設定ファイル
┃ ┗ db_data MySQLの動作ファイル
┗ src Laravelのルートフォルダ
docker-compose.yml
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
container_name: laravel12__tpj
volumes:
- ./src:/var/www/html
ports:
- "8080:80"
depends_on:
- db
working_dir: /var/www/html
networks:
- laravel-net
db:
image: mysql:8.4
container_name: mysql84__tpj
restart: always
environment:
MYSQL_ROOT_PASSWORD: pass001
MYSQL_DATABASE: laradb
MYSQL_USER: laravel
MYSQL_PASSWORD: larapass
ports:
- "3306:3306"
volumes:
- ./docker/db_data:/var/lib/mysql
networks:
- laravel-net
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: pma__tpj
restart: always
ports:
- "8888:80"
environment:
PMA_HOST: db
PMA_PORT: 3306
UPLOAD_LIMIT: 100M
depends_on:
- db
networks:
- laravel-net
networks:
laravel-net:
docker/Dockerfile
FROM php:8.2-apache
# 必要なパッケージのインストール
RUN apt-get update && apt-get install -y \
libzip-dev zip unzip git curl libonig-dev \
&& docker-php-ext-install pdo_mysql mbstring zip
# Composerのインストール
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
# Apacheのmod_rewriteを有効化
RUN a2enmod rewrite
# ドキュメントルート指定
RUN sed -i 's|DocumentRoot /var/www/html|DocumentRoot /var/www/html/public|g' /etc/apache2/sites-available/000-default.conf
# ワークフォルダの変更
WORKDIR /var/www/html
まとめ
今回はdocker composeで、PHP 8.2、MySQL 8.4 の環境を作成し、Laravel 12をセットアップしました。
この手順を少し修正すれば、PHP・MySQL・Laravelいずれも好きなバージョンを選ぶことができますし、Laravelに限らず、PHPとMySQLで動作するものは大抵動かせると思います。環境が出来てしまえば、upとdownコマンドで起動を切り替えられるので相当便利と思います。試してみてください。
独学のため正確でない可能性があります。
(っ・x・)っ きゅ