はじめに
- Laravel のコードを全て Dokcer コンテナの中に入れ、単一の Docker コンテナにする。
- Go 言語における、ビルドして作成したバイナリのみ Docker コンテナに含めるようにし、 Docker コンテナをアプリとして扱うような感覚に近い。
- Laravel のコードをコンテナとホストでボリューム共有するような、開発環境のために Docker を使う構成ではない。
今回行うこと
- Laravel のウェルカムページを表示するだけの Docker コンテナを作る。
- Docker コンテナ化することを今回の第一の目的とする。そのため、
composer install
などは Docker ホストで行う。 - ベースの Docker コンテナは php-apache とする。 php-fpm と Nginx だと、 Nginx 用のコンテナを別途用意するか、 Nginx をコンテナ内にインストールしなければならず、手間がかかる。今回は、簡単に行う。
環境
- Docker version 19.03.1, build 74b1e89
- Composer version 1.9.0 2019-08-02 20:55:32
Laravel アプリを用意する
composer create-project --prefer-dist laravel/laravel sample_dockerized_laravel6
cd sample_dockerized_laravel6/
http://127.0.0.1:8000 にアクセスして、 Laravel ウェルカムページが表示されました。
Dockerfile を用意する
dockerized_laravel/Dockerfile
を作成し、次の内容としました。これを使用すれば、 Laravel アプリを Docker 化できるようになりました。
- ウェブサーバを別途作成するのは手間なので、Apache も同梱されている
php:<version>-apache
コンテナをベースとした。 ARG TZ=Asia/Tokyo
の下りは、タイムゾーン設定。コンテナ内でenv
コマンドで確認できるよう、ENV TZ ${TZ}
でコンテナの環境変数にも設定RUN apt-get update && apt-get install -y \
の下りは、 Laravel に必要な PHP 拡張モジュール を追加している。ENV APACHE_DOCUMENT_ROOT /var/www/html/public
の下りは、 Laravel はpublic/index.php
へのアクセスをウェブサーバのドキュメントルートとする必要があるので設定。 php – Docker Hub の "Changing DocumentRoot (or other Apache configuration)" をそのまま利用した。COPY . .
でdockerized_laravel/
ディレクトリ内の全てを Docker コンテナへとコピーした。RUN chown -R www-data:www-data /var/www/html/
は補足で詳細を解説しているが、エラーとなるので必要だった。
FROM php:7.3-apache
ARG TZ=Asia/Tokyo
ENV TZ ${TZ}
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y \
libzip-dev \
&& docker-php-ext-install \
bcmath \
pdo_mysql \
zip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
COPY . .
RUN chown -R www-data:www-data /var/www/html/
Docker化の実行、確認
動作確認として、 docker container run
後、 http://127.0.0.1/
へアクセスしてウェルカムページが表示されることを確認できました!
# ビルド
docker build -t sample_dockerized_laravel6 .
# 動作確認
docker container run -d --rm -p 80:80 --name sample_dockerized_laravel6 sample_dockerized_laravel6:latest
# コンテナ内に入る
docker container exec -it sample_dockerized_laravel6 bash
# 停止
docker container stop sample_dockerized_laravel6
補足
ビルド時に気になったこと。ビルド対象のサイズが大きく感じる。
docker build
時、最初の次の出力が気になりました。
$ docker build -t sample_dockerized_laravel6 .
Sending build context to Docker daemon 47.72MB
... 略 ...
まず、コマンドの基本のおさらいです。 docker build -t name:tag PATH
でビルドします。 PATH で指定したディレクトリをコンテクストと呼び、コンテクストをビルドで使用します。
今回、 Sending build context to Docker daemon 47.72MB
とありますので、コンテクストは 47.72MB もあります。これは、ほとんどが comoposer install で vendor/ に追加した依存パッケージです。
編集しない依存パッケージを、毎回ビルド時にコピーするのは時間が勿体無く感じます。編集対象のプロジェクトコードのみをコピーするようにできたら、もっとビルド時間を短縮できるのではないでしょうか?
コンテナを起動して気が付いたこと。ログに書き込めないエラー。
試行錯誤している段階の時のことです。ビルド後、 http://127.0.0.1/
にアクセスすると、次のようにエラーが表示されました。
UnexpectedValueException The stream or file "/var/www/html/storage/logs/laravel-2019-10-22.log" could not be opened: failed to open stream: Permission denied http://127.0.0.1/
これの対処は、 chown -R www-data:www-data /var/www/html/
をして、所有者を root:root から変更すれば解決 しました。
他にコンテナを起動して気が付いたこと。 DB に接続できないという内容の出力がされました。
DB 設定をしていないためです。今回は対象外ですけれども、いずれ必要となってきます。 Docker コンテナ化しているので、 Docker の引数で設定できるようにできれば、便利です。
Database name seems incorrect You’re using the default database name laravel. This database does not exist.
Edit the .env file and use the correct database name in the DB_DATABASE key
おわりに
今回のソース全体です。
最初の一歩として、最も単純な Laravel アプリを Docker 化することができました! 次は、以下のようなことをやっていきたいです。
- php.ini の date.timezone 等の設定
- Docker ログ出力
- mod_rewrites の設定
- DB 設定
- composer install で追加する依存パッケージを、 Docker ビルド時のキャッシュにする
- npm install で追加する依存パッケージを、 Docker ビルド時のキャッシュにする
以上です。