Laravel向けのDocker開発環境を整えたので共有します。
本番でもDockerが使えるように色々試しているとこですので、自分が把握できた範囲の構成です。
githubに置いときます。
目標とミドルウェアの構成
目標はDockerを立ち上げて直ぐにLaravelの開発ができるようにすること。composerとnodejsも一緒に用意します。
構成とバージョン。最新になるようにしています。
- php (php-fpm) 7.4.1
- composer 1.10.13
- nodejs v12.18.4
- npm 6.14.6
- mysql 8.0 (5.7も可能)
- パスワードなど初期設定をする。
- nginx 1.19.2
- Laravel向けのconfを用意する。
ホスト環境
今回の趣旨に関係ありませんが、ホストOSはWindows10です。
- Windows 10 Home バージョン2004(OSビルド 19041.508)
- WSL2 (Ubuntu 20.04.1 LTS)
- Docker version 19.03.13, build 4484c46d9d
- docker-compose version 1.27.4, build 40524192
WSL2が出てWindows HomeでもDockerが使えるようになりました。 インストール方法はMicrosoftの手順を解説したQiita @KoKeCrossの記事の通り進めて行けばOKです。
ディレクトリ構成
/project
├─ /docker # コンテナ内のデータ保存先
| ├─ /db
| | ├─ /data # データベース保存先
| | ├─ /sql
| | └─ /my.conf # mysqlの設定(今回は空ファイル)
| ├─ /nginx
| | └─ /default.conf # Nginxの設定
| └─ /php
| ├─ /Dockerfile # phpコンテナの設定
| └─ /php.ini # phpの設定
├─ /web # アプリケーションコード
└─ docker-compose.yml
docker-compose.yml
php, nginx, dbのコンテナを作ります。mysqlはdb。
version: '3'
volumes:
vendor-store:
node_modules-store:
services:
php:
container_name: php
build: ./docker/php
volumes:
- ./web:/var/www
- vendor-store:/var/www/laravel/vendor
- node_modules-store:/var/www/laravel/node_modules
environment:
TZ: Asia/Tokyo
nginx:
image: nginx
container_name: nginx
ports:
- 80:80
volumes:
- ./web:/var/www
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
db:
image: mysql:8.0
container_name: db
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: database
MYSQL_USER: docker
MYSQL_PASSWORD: docker
TZ: 'Asia/Tokyo'
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
volumes:
- ./docker/db/data:/var/lib/mysql
- ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
- ./docker/db/sql:/docker-entrypoint-initdb.d
ports:
- 3306:3306
imageはDocker-Hubにあるビルド済みイメージを指定している。 有名なミドルウェアは公式のものがあります。 phpコンテナはNodejsやcomposerをインストールするため、Dockerfileからビルドします。
volumesはホストとコンテナのディレクトリとファイルを同期する。
ホストの/web
をphp・nginxコンテナのエントリーポイント/var/www
に指定しました。
Laravelプロジェクトは/web
にクローンするか、phpコンテナの/var/www
で新規作成して開発が可能です。
vendorとnode_modulesは名前付きボリュームに格納して、ホスト側とコンテナ側と分離して管理している。 同期処理が発生しないため、その分速くなる。
dbのenvironmentに初期設定を渡せる。 これを.envに書いたり、ホストのSQLクライアントの接続にそのまま使えます。 その他の変数はdockerhub mysqlでご確認ください。
mysql:8.0
をmysql:5.7
にしても動作確認とれた。
php/Dockerfile
FROM php:7.4.1-fpm
COPY php.ini /usr/local/etc/php/
RUN apt update
RUN apt install -y wget git unzip libpq-dev
# Install Node.js 12
RUN apt install -y npm \
&& npm install n -g \
&& n 12
# Install PHP Extensions
RUN apt install -y zlib1g-dev mariadb-client libzip-dev libonig-dev \
&& docker-php-ext-install zip pdo_mysql
# Install Composer
RUN curl -sS https://getcomposer.org/installer | php \
&& mv composer.phar /usr/local/bin/composer \
&& composer self-update
WORKDIR /var/www
# php-fpmはデフォルトのユーザwww-dataで動く。https://stackoverflow.com/questions/48619445/permission-denied-error-using-laravel-docker
# 変更する場合は /usr/local/etc/php-fpm.d/www.conf でユーザー名を変える。
RUN chown -R www-data:www-data /var/www
RUN composer global require "laravel/installer"
php:7.4.1-fpm
のイメージにNode.jsやComposerをインストールしていくDockerfileです。
aptだとNodejsは古いため、パッケージマネージャのnで新しいバージョンをインストールしています。 以下のようにスクリプトでインストールする方法もあります。
# Install Node.js 12
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - \
&& apt install -y nodejs
php 7.4ではビルド時にonigumaが見つからないとエラーが出ます。
aptではlibonig-dev
(library onigumaかな?)をインストールすると回避できる。
参考1,参考2
必要な拡張はdocker-php-ext-installに追加していく。
nginxはphp-fpmを通してLaravelを実行します。
/var/www
以下のファイルにユーザwww-dataの実行権限を与えます。
www-dataはphp-fpmのデフォルトユーザです。
/usr/local/etc/php-fpm.d/www.conf
を修正してユーザ名を変更できます。
/php/php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
cliもfpmのphpもこの設定を参照します。
/nginx/default.conf
server {
listen 80;
// root /var/www/{Laravelプロジェクト名}/public;
root /var/www/laravel/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
// phpファイルはfastcgi(=php-fpm)で処理するよって書いてある
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;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
LaravelをNginxで動作させる設定です。 ApacheではLaravel同梱の.htaccessが設定してくれるが、Nginxでは.htaccessに当たるものがないためNginxのconfを修正する必要がある。(.htaccessを極力使わないほうがいい)
公式の設定Nginx | laravel.comからphpコンテナのfpmを見るよう修正しています。 ネットワークはDockerに管理されており、ホスト名はコンテナ名と同等です。
ドキュメントルートを/var/www/laravel/public
としています。
プロジェクト名が変わるときはパスに注意。
docker-composeのコマンド
ホスト側でよく使うコマンドです。
# コンテナ起動
$ docker-compose up -d
# コンテナ削除
$ docker-compose down
# コンテナ、イメージ、ボリューム、ネットワークを一括完全消去
$ docker-compose down --rmi all --volumes
# phpコンテナに接続する(コンテナ名を変えて他のコンテナに接続できる)
$ docker-compose exec php bash
Dockerfileなど修正した場合は一括削除してから起動しなおすといい。
初回はLaravel 8.x インストールに従ってphpコンテナ内で作業するとプロジェクトを作成できます。
ログの書き込みなどでpermission deninedが出る場合は、# chown -R www-data:www-data /var/www
を実行するとphp-fpmに権限が与えられて解消できます。(php-fpmユーザを変更した場合はそのユーザ名にする)
参考
DockerFile
Dockerの操作
書籍
Dockerって何?の状態で読むと難しすぎたが、Dockerの概念を他で学び試して遊んでからわかるようになった。 Dockerの運用管理向け、業務で何度も読み返しそうな良著。