これならわかるDocker上にLaravel環境構築
Docker上にLaravelの開発環境を構築したい場合に最初に思いつくのはLaradockかもしれません。手順通りに進めればLaravel環境を構築することができたが何がどのように設定されているのかわからないでも動くからいいやと人も多いと思います。本文書ではDockerについての基礎を学びながらできるだけシンプルにLaravel環境の構築を行っていきます。
最初にLaravelコンテナ単体で動作確認を行い、MySQLコンテナ、Nginxコンテナを追加して最終的には3つのコンテナで動作する環境を構築します。
作業はMac環境で行い、docker、docker-composeコマンドが利用できる状態から開始します。
Laravelコンテナの作成
最初にLaravelコンテナの作成を行い、インストール後に表示されるトップ画面、ユーザ登録画面の表示までの手順を確認していきます。
任意の場所にプロジェクトディレクトリlaravel_dockerを作成し、作成したディレクトリに移動します。本環境では/Users/reffect/Desktopの下に作成しています。
% mkdir laravel_docker
% cd laravel_docker
docker-compose.ymlファイル作成
Laravelのインストールを行うコンテナを作成するためにdocker-compose.ymlを作成します。docker-compose.ymlを利用することで複数のコンテナを一度に作成、制御することが可能になり効率的に環境構築を行うことができます。 最初は1つのコンテナの設定情報のみを記述しますが、後ほどMySQL, Nginxの設定に必要な情報もこのファイルに追記していきます。
作成したdocker-compose.ymlの内容は下記の通りです。
version: '3.7'
services:
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./src:/var/www/html
ports:
- "8000:8000"
- versionではdocker-composeのフォーマットにはバージョンがあり、現在最新である3.7を指定しています。バージョンにより記述方法が異なります。
- servicesにphpが設定されていますが、このphpがコンテナを表しており、container_nameではコンテナの名前を指定しています。phpというコンテナ名で他のコンテナと区別することができます。後ほど追加するデータベースはdb、WebサーバのNginxはnginxとしてservicesを設定します。
- buildの下のcontextとdockerfileはイメージをビルドするために必要な情報が記述されたDockerfileへのパスとファイル名を指定しています。contextの.(ドット)はdocker-compose.ymlと同じディレクトリを意味し、dockerfileのDockerfileはファイル名を指定しています。docker-compose.ymlディレクトリの中にあるDockerfileをビルドで利用することになります。
- volumesではローカルのディレクトリとコンテナ上のディレクトリのリンクを設定しています。./srcはdocker-composer.ymlのディレクトリ直下にあるsrcを設定しています。コンテナが作成されるとsrcディレクトリからコンテナの/var/www/htmlにアクセスすることができます。
- portsではローカル側のポートとコンテナ側のポートを設定しています。8000ポートにアクセスするとコンテナ側の8000にアクセスすることができます。
Dockerfileについて
Dockerfileにはコンテナに利用するイメージ情報とそのイメージに追加するパッケージや構成変更を行うコマンド等を記述することができます。イメージ情報に構築するユーザ毎の個別の設定を追加しておくことで全く同じ環境を容易に構築することができます。
今回利用するDockerfileの記述量は少ないですが、FROMでコンテナの元になるイメージのphp:7.4-fpm-alpineを指定し、RUNでモジュールのインストールを行うdocker-php-ext-install pdo pdo_mysqlコマンドが記述されています。
LaravelではPHPを利用するためphp:7.4-fpm-alpineのイメージを利用します。
FROM php:7.4-fpm-alpine
RUN docker-php-ext-install pdo pdo_mysql
コンテナの作成
docker-compose.ymlとDockerfileが作成できたので、docker-composeコマンドを利用してコンテナの作成を行います。
docker-composeコマンドは実行時にdocker-compose.ymlファイルの中身を確認するためのdocker-compose.ymlファイルが存在するディレクトリで実行してください。
% docker-compose up -d
イメージ(php:7.4-fpm-alpine)がローカルにない場合はダウンロードを行い、ビルドを行うので初回は少し時間がかかります。2回目からはダウンロードしたイメージを利用するため短い時間で処理が完了します。
docker-compose ps -aコマンドを実行すると作成したコンテナのステータスを確認することができます。State列がUpになっているので起動していることがわかります。
% docker-compose ps -a
Name Command State Ports
-------------------------------------------------------------------------------
php docker-php-entrypoint php-fpm Up 0.0.0.0:8000->8000/tcp, 9000/tcp
Laravelのインストール
コンテナの作成が完了したので、Laravelのインストールを行います。Laravelをコンテナ上にインストールするためにはcomposerが必要になります。composerもDockerのコンテナを利用することができます。
composerコンテナを利用して./srcディレクトリにLaravelのインストールを行います。
% docker run --rm -v /Users/reffect/Desktop/laravel_docker/src:/app composer create-project --prefer-dist laravel/laravel .
–rmを付けて実行するとコンテナ作成後処理が完了すると自動で削除されます。
-vオプションでは、ローカルPCのディレクトリとcomposerコンテナ上の/appディレクトリを紐づけています。そのため上記のコマンドを実行すると./srcディレクトリの下にLaravelに関連するディレクトリ、ファイルが保存されます。/appを別の場所に設定して実行すると./srcディレクトリには何も保存されません。
開発サーバの起動
Webサーバの設定を行っていないので開発サーバを起動することでLaravelのトプ画面を表示できるように下記の設定を行います。docker exec -it php コマンドでphpコンテナのコマンドをローカルから実行することができます。
% docker exec -it php php artisan serve --host=0.0.0.0 --port=8000
php artisan serveだけではローカルアクセスできないので注意してください。
このコマンド実行後、ブラウザで127.0.0.1:8000(or 0.0.0.0:8000)にアクセスするとトップ画面が表示されます。
laravel/uiパッケージのインストール
ユーザの認証の画面を作成するために必要となるlaravel/uiパッケージのインストールを行います。PHPのパッケージのインストールにはcomposerが必要となるのでLaravelのインストールと同様にcomposerコンテナを利用します。
% docker run --rm -v /Users/reffect/Desktop/laravel_docker/src:/app composer require laravel/ui
laravel/uiパッケージのインストールが完了したら、php artisanコマンドを実行します。このコマンドで認証画面の追加が行われます。
% docker exec -it php php artisan ui vue --auth
Vue scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.
Authentication scaffolding generated successfully.
実行後はメッセージに表示されている通りnpm install && npm run devでJavaScript関係パッケージのインストールとビルドが必要になります。
nodeコンテナの利用
npmコマンドを利用するためにはnodeが必要になります。nodeもcomposerと同様にコンテナを利用して実行します。
% docker run --rm -v /Users/reffect/Desktop/laravel_docker/src:/usr/src/app -w /usr/src/app node npm install && npm run dev
composerの場合は-vで/appを指定していましたが、nodeの場合は/usr/src/appを指定した上、-w(working_dir)で/usr/src/appを指定しています。
実行するとインストールとビルドが行われます。
開発サーバを起動した状態でアクセスするとログイン画面を表示することができます。
ログイン画面が表示されましたが、ユーザを登録を行うとエラーが発生します。理由はLaravelからデータベースに接続することができないためです。次はMySQLコンテナを追加します。
続きます。
MySQLコンテナの作成
MySQLコンテナを利用してLaravel上で生成されるデータを保存します。
docker-compose.ymlファイルへの追加
sericesにmysqlを追加します。
version: '3.7'
services:
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./src:/var/www/html
ports:
- "8000:8000"
mysql:
image: mysql:5.7
container_name: mysql
ports:
- "3306:3306"
volumes:
- ./db:/var/lib/mysql
- ./my_conf:/etc/mysql/conf.d
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: laravel
- Laravelコンテナの場合はdockerfileを利用しましたが、MySQLコンテナではイメージをそのまま使うためimageでmysql:5.7を設定しています。5.7はMySQLのバージョンを表しています。mysql:latestと設定すると最新版になります。
- コンテナ名であるcontainer_nameはmysqlを設定しています。
- portsはMySQLのデフォルトポートの3306を利用しローカル環境から3306ポートを使ってMySQLのデータベースに接続することができます。ローカルでMySQLデータベースが動作している場合は3307:3306を設定してポートが重複しないようにしてください。
- volumesには2つ設定していますが、./dbにはMySQLコンテナに保存されているデータとローカルディレクトリの./dbを紐づけています。my_confはMySQLコンテナの設定ファイルが保存されているディレクトリと紐づけています。
- environmentではMySQLのrootユーザのパスワードとデータベースの設定のみ行っています。
Volumesの作成
docker-compose.ymlで設定したdbとmy_confディレクトリを作成します。
% pwd
/Users/reffect/Desktop/laravel_docker
% mkdir db
% mkdir my_conf
my_confの下には設定ファイルmysql5.7.cnfファイルを作成し、日本語対応できるように文字コードの設定を行います。
[mysqld]
character-set-server=utf8mb4
[client]
default-character-set=utf8mb4
MySQLコンテナの作成
MySQLコンテナを作成する前に一度Laravelコンテナの削除をしておきます。docker-compose downコマンドを実行するとコンテナの停止と削除を同時に行います。
% docker-compose down
Stopping php ... done
Removing php ... done
Removing network laravel_docker_default
LaravelコンテナとMySQLコンテナを作成します。docker-compose.ymlにコンテナ情報が記述されているのでdocker-compose up -dコマンドで2つのコンテナが作成されます。
% docker-compose up -d
Creating network "laravel_docker_default" with the default driver
Creating mysql ... done
Creating php ... done
作成したら正常に起動しているか確認しておきます。
% docker-compose ps -a
Name Command State Ports
---------------------------------------------------------------------------------
mysql docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
php docker-php-entrypoint php-fpm Up 0.0.0.0:8000->8000/tcp, 9000/tcp
State列がexitになり起動していない場合はdocker logs コンテナ名を実行してログを確認してください。
Laravelからの接続
Laravelから接続するためにはデータベースの環境変数が記述されている.envファイルを更新する必要があります。srcディレクトリ内にある.envファイルを開いてデータベースの接続に関する設定を下記のように更新してください。
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=password
.envファイルの設定がしたら、php artisan migrateコマンドを実行してデータベースにテーブルが作成されるか確認しましょう。
接続が正常に行われた場合は下記のようなメッセージが表示されます。
% docker-compose exec php php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (0.09 seconds)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (0.05 seconds)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (0.03 seconds)
ここまでの設定でLaravelコンテナとMySQLコンテナな接続完了です。次はNginxコンテナの作成を行います。
Nginxコンテナの作成
ここまでは開発サーバを起動してLaravelへアクセスを行っていましたがNginxコンテナを作成し、Webサーバ経由でLaravelにアクセスします。
docker-compose.ymlファイルへの追加
docker-compose.ymlへの追加についてはphpとMySQLコンテナと同じです。
version: '3.7'
services:
php:
build:
context: .
dockerfile: Dockerfile
container_name: php
volumes:
- ./src:/var/www/html
ports:
- "9000:9000"
mysql:
image: mysql:5.7
container_name: mysql
ports:
- "3306:3306"
volumes:
- ./db:/var/lib/mysql
- ./my_conf:/etc/mysql/conf.d
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: laravel
nginx:
image: nginx:stable-alpine
container_name: nginx
ports:
- "8080:80"
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
- mysql
nginxではimageはnginxのstable-alpineを使います。
コンテナ名のcontainer_nameにはnginxを設定します。
ポートはローカルから8080でアクセスできるように8080:80を設定しています。
volumesの設定の1つはphpと同じ設定を行っています。もう一つはnginxの設定ファイルを指定します。設定ファイルはこの後作成します。
phpのポートを先ほどまで8000:8000に設定していましたが、9000:9000に変更を行ってください。Nginxと通信する際にポート9000を利用するためです。
nginxの設定ファイルの作成
ローカル上に設定ファイルを保存するnginxディレクトリを作成します。
% pwd
/Users/reffect/Desktop/laravel_docker
% mkdir nginx
nginxディレクトリにはNginxの設定ファイルdefault.confファイルを作成し、下記のように記述します。
server {
listen 80;
index index.php index.html;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/html/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
設定している中身はDockerではなくNginxに関する設定なので詳細は説明しませんが、rootの箇所の/var/www/html/publicがlaravelのインストールディレクトリの下にあるpublicと一致する必要があります。
コンテナの作成
Nginxの設定が完了したので、コンテナの作成を行いますが作成を行う前に先ほど作成したLaravelとMySQLのコンテナは削除しておきます。
% docker-compose down
Stopping php ... done
Stopping mysql ... done
Removing php ... done
Removing mysql ... done
Removing network laravel_docker_default
コンテナの作成を行います。
% docker-compose up -d
Creating network "laravel_docker_default" with the default driver
Creating mysql ... done
Creating php ... done
Creating nginx ... done
起動しているか確認を行います。
% docker-compose ps -a
Name Command State Ports
---------------------------------------------------------------------------------
mysql docker-entrypoint.sh mysqld Up 0.0.0.0:3306->3306/tcp, 33060/tcp
nginx nginx -g daemon off; Up 0.0.0.0:8080->80/tcp
php docker-php-entrypoint php-fpm Up 0.0.0.0:9000->9000/tcp
起動後ブラウザから127.0.0.1:8080にアクセスしてLaravelのトップページが表示されたらNginx経由でLaravelにアクセスしていることになります。
ユーザの登録やログインが行えるか一通り動作確認を行ってください。
ここまでの設定でLaravelにNginx経由でアクセスしMySQLデータベースへのデータの登録まで行えることを確認しました。最もシンプルなdocker-compose.ymlなので各自の要件に合うようにカスタマイズを行ってください。