Laravel 6 を Docker 化する。その 1 。Laravel のコード全てを `php:-apache` Docker コンテナに含める

はじめに

  • 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 ビルド時のキャッシュにする

以上です。

コメントを残す

コメントを残す