はてなの金次郎

Pythonエンジニアの技術系ブログ

Docker ComposeでLaravelのお手軽開発環境構築

はじめに

Laravel #2 Advent Calendar 2018 の5日目の記事です。

qiita.com

Docker Composeの公式HPで「Quickstart: Compose and Django」や「Quickstart: Compose and Rails」のようにDjangoRailsのクイックスタートはあるのですが、Laravelのクイックスタートが残念ながらありませんでした。

そこで今回、Laravelの公式HPで公開されているチュートリアルBasic Task List」を元にDocker Composeのチュートリアル的なもの「Quickstart: Compose and Laravel」 を作成してみました。

コンテナ構成はLaravel + MySQL + Redisです。

コンテナ技術の動向

コンテナ技術の動向や有用性を知ることでコンテナを学ぶべき理由を改めて認識したいと思います。

コンテナ化したアプリケーションを活用するクラウドネイティブの流れが進行しています。
(中略)
インフラを意識せず、ソフトウェアやサービスの開発に集中することができ、結果として高品質なサービスを提供できる機会が高まりつつあるといえるでしょう。

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤

サービスのコンテナ化というのはここ数年のWeb業界の一大トレンドというか完全に一般化してきています。
(中略)
ローカル環境でのテストや、CI上でのテストに関してもDockerを使用することが当然の流れのようになってきています。

qiita.com

全てのソフトウェアにコンテナ技術が適しているわけではありませんが、コンテナ技術はもはやデファクトスタンダードという言葉では表現できないものになっています。

まさに「衣・食・住・コンテナ」と言っても過言ではないでしょう。(過言です)

Docker Composeの便利さを体感してみる

まずは実際にDocker Composeで開発環境を構築してその便利さを体感してみてください。
わずか数コマンドで開発環境を構築できてしまいます。

ソースコードGitHubで公開しています。

github.com

まず、ソースコードをクローンします。

$ git clone https://github.com/jumpyoshim/quickstart-compose-and-laravel.git

環境変数を定義しているファイルをコピーし、Laravelのアプリケーションキーを生成します。

$ cp .env.example .env
$ php artisan key:generate

バックグラウンドで複数コンテナを起動します。

$ docker-compose up -d

これで開発環境の構築は完了です。 http://0.0.0.0:8000/ にアクセスしてみましょう。
アプリケーションの起動が確認できると思います。

f:id:gyuuuutan:20181202021716p:plain
ルートパスにアクセスしたときの画面

さらに、起動したコンテナでユニットテストを走らせることもできます。

$ docker-compose exec app bash
# composer test

Docker Composeによる開発環境構築

Dockerfileの作成

それではDocker Composeの開発環境構築の手順を紹介します。
まずはLaravelアプリケーションのDockerfileの作成です。

Docker は Dockerfile から命令を読み込み、自動的にイメージを構築できます。 Dockerfile はテキスト形式のドキュメントであり、コマンドライン上でイメージを作り上げる命令を全て記述します。ユーザは docker build を使い、複数のコマンド行の命令を順次実行し、イメージを自動構築します。

参考:http://docs.docker.jp/engine/reference/builder.html

FROM php:7-fpm

RUN set -x \
    && apt update \
    && apt install -y --no-install-recommends \
      git \
      wget \
    && docker-php-ext-install \
      pdo_mysql \
      mysqli \
      mbstring

ENV COMPOSER_ALLOW_SUPERUSER 1
RUN curl -sS https://getcomposer.org/installer | php \
    && mv composer.phar /usr/local/bin/composer

ENV DOCKERIZE_VERSION v0.6.1
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz

RUN mkdir /app
WORKDIR /app
ADD . /app/
  • FROM php:7-fpm:ベースイメージを指定します。DockerHubで公開されている公式イメージや、は独自のコンテナレジストリのイメージを指定します。セキュリティの観点から個人で公開しているイメージを指定するのはあまり望ましくないでしょう。
  • RUN set -x \ ...:必要なパッケージ群をインストールします。
  • RUN curl -sS ...Composerをインストールします。
  • RUN wget ...dockerizeをインストールします。dockerizeを利用することでコンテナの起動順を担保します。
  • RUN mkdir /appapp ディレクトリを作成します。
  • WORKDIR /app:ワーキングディレクトリを指定します。
  • ADD . /app/:カレントディレクトリのソースコード等を app ディレクトリにコピーします。

docker-compose.ymlの作成

次に docker-compose.yml を作成します。これは複数コンテナの管理を定義するファイルです。

Compose とは、複数のコンテナを使う Docker アプリケーションを、定義・実行するツールです。Compose はアプリケーションのサービスの設定に、Compose ファイルを使います。そして、コマンドを1つ実行するだけで、設定した全てのサービスを作成・起動します。

参考:http://docs.docker.jp/compose/overview.html

version: '3'

services:
  db:
    image: mysql:5
    environment:
      MYSQL_DATABASE: tasklist
      MYSQL_ROOT_PASSWORD: secrets
  app:
    build: .
    command: >
      bash -c "dockerize -wait tcp://db:3306
      && composer install --no-plugins --no-scripts
      && php artisan migrate
      && php artisan serve --host=0.0.0.0 --port=8000"
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    env_file:
      - .env
    depends_on:
      - db
  redis:
    image: redis:5

services に開発環境を構成するコンテナを定義します。
今回は db, app, redis の3つのコンテナを定義します。
Nginxなどのコンテナを定義することでより本番環境に近い環境を構築することも可能です。

  • db:データベース名やパスワードを設定します。
  • app:先ほど作成したDockerfileを元にコンテナを起動します。Composerでライブラリのインストール、マイグレーション、アプリケーションの起動を追加で行います。
  • redis:特にイメージのカスタマイズが必要なければイメージの選択だけでもコンテナを起動できます。

おわりに

Docker Composeを利用することでお手軽に開発環境を構築できたかと思います。
Docker Composeを利用すれば以下のメリットを享受できます。

  • 複数のコンテナをコマンド1つで起動・停止が可能
  • コマンド実行時にコンテナ間の依存関係を意識する必要がない
  • コンテナの構成情報はCI/CDにもそのまま利用できる

Dockerは開発環境の構築だけではなく、本番環境のデプロイに使用すると価値が出てくる。開発時の環境分離だけに使用するとオーバーヘッドも大きく、本番環境と一致しないという欠点を抱えてしまう

エキスパートPythonプログラミング 改訂2版 (アスキードワンゴ)

エキスパートPythonプログラミング 改訂2版 (アスキードワンゴ)

当たり前ですが、開発環境は本番環境に合わせて構築するべきです。

例えば、Amazon ECS + ECS CLIで本番環境を構築する場合はDocker Composeによる開発環境構築はとても有効的だと思います。ECS CLIはdocker-compose.ymlの構成情報をもとにタスク定義を行い、タスクを実行するためです。

同じように、本番環境の構築にKubernetesを利用する場合はMinikubeが有効的だと思います。

とっても便利なDocker Composeですが、銀の弾丸ではありません。ソフトウェアにとって最適なインフラ構成、そして本番環境に最適な開発環境の構築ができるような力を身につけていきたいですね。