Help us understand the problem. What is going on with this article?

Laravelで最適なDocker環境を作る

More than 3 years have passed since last update.

この記事はこちら の構成の具体的な説明となります

ディレクトリ、ファイル構成

├── docker
│   ├── docker-compose.yml
│   ├── composer
│   │   └── Dockerfile
│   ├── data
│   │   └── Dockerfile
│   ├── fpm
│   │   ├── Dockerfile
│   │   └── php-fpm.d
│   │       ├── docker.conf
│   │       ├── www.conf
│   │       ├── www.conf.default
│   │       └── zz-docker.conf
│   ├── gulp
│   │   └── Dockerfile
│   ├── nginx
│   │   ├── Dockerfile
│   │   └── config
│   │       ├── laravel.conf
│   │       ├── nginx.conf
│   │       └── nginx_run.sh
│   └── npm
│       └── Dockerfile
├── logs
└── www

各種説明

こちらは各プロセスごとにディレクトリを分割し、それ専用のDockerfileを作成、docker-compose.ymlでそれらのビルド設定を記載し、一括ですべての環境を開始できるようにしています。

docker-compose.yml

version: "2" # docker-composeのversion2を使用
services: # 各種サービスの設定
  data: # データボリューム用コンテナ、ソースやDBのデータ等開発で生成するものはここにマウント
    build: ./data
    volumes:
      - ../:/data
      - /var/lib/mysql
  db: # DBストア
    image: mariadb
    volumes_from:
        - data
    environment:
      MYSQL_ROOT_PASSWORD: pass
  fpm: # php-fpm: PHPプロセスを実行するコンテナ
    build: ./fpm
    volumes_from:
      - data
  nginx: # php-fpmにリバースプロキシする
    build: ./nginx
    volumes_from:
      - data
    links:
      - fpm:fpm
    ports:
      - "80:80"
  composer: # composerコマンドを実行するときに都度実行
    build: ./composer
    volumes_from:
      - data
  gulp: # gulpコマンドを実行するときに都度実行
    build: ./gulp
    volumes_from:
      - data
  npm: # npmコマンドを実行するときに都度実行
    build: ./npm
    volumes_from:
      - data

db

FROM debian:jessie

MAINTAINER "Kota Matsumoto" <kota1861@gmail.com>

RUN mkdir -p /data
VOLUME ["/data"]
CMD ["true"]

このように/dataディレクトリを作成し、そこにボリュームマウントできるようにしているだけです。
使用しているimageはdebian:jessieを使っていますが、これは他のサービスもこれを使っているからで、他のimadeでも問題ありません。

fpm

FROM php:7.0.12-fpm

MAINTAINER "Kota Matsumoto" <kota1861@gmail.com>

RUN apt-get update -y

# clean fpm conf
# RUN rm /usr/local/etc/php-fpm.d/*
COPY php-fpm.d /usr/local/etc/php-fpm.d

RUN mkdir -p /data
VOLUME ["/data"]

phpのDockerhubで公式にfpm用のimageを提供しているので、そちらを使っています。
ちなみにgithub上に元のDockerfileがあります。

なるべく最新のpackageを使いたいので、apt-get updateを行い、php-fpm.dに設置してあるfpm用の設定ファイルをコピーしています。

nginx

FROM nginx

MAINTAINER "Kota Matsumoto" <kota1861@gmail.com>

COPY config/nginx.conf /etc/nginx/nginx.conf
COPY config/laravel.conf /etc/nginx/conf.d/laravel.conf
RUN rm /etc/nginx/conf.d/default.conf

RUN mkdir -p /data
VOLUME ["/data"]

nginxではphp-fpmを使用するため若干トリッキーなことをしています。
というのも、nginxからfpmのコンテナに向けてリバースプロキシをするために、サーバーのホスト名・ポート番号を下記のように指定する必要があるのですが

http {
    upstream phpfpm_backend {
        server fpm:9000;
    }
    ...
}

このfpmというのが、fpmサービスが提供しているもので、同じdocker-compose内だとこのサービス名がホスト名の名前解決に使われます。

またlogの出力先として/data/logsを指定しているので、実行後のログはホストのlogsディレクトリに逐一反映されます

nginx.conf
    access_log /data/logs/access.log;
    error_log /data/logs/error.log warn;

gulp

FROM debian:jessie

MAINTAINER "Kota Matsumoto" <kota1861@gmail.com>

RUN apt-get update -y
RUN apt-get install -y curl git
RUN curl -sL https://deb.nodesource.com/setup | bash --
RUN apt-get install -y nodejs
RUN npm update -g npm
RUN npm cache clean
RUN npm i -g n
RUN n stable
RUN apt-get purge -y nodejs npm
RUN npm i -g gulp-cli

RUN mkdir -p /data/www
VOLUME ["/data"]
WORKDIR /data/www

ENTRYPOINT ["gulp"]
CMD ["-h"]

最新のnodejsをinstallし、npmを最新にしています。
nパッケージを使用しているのは、apt-getに乗っかっているnodeだとgulpをインストールするバージョンに達しないため、nパッケージを使ってnodejsのバージョンを上げています。
ただ、nパッケージをインストールするにはnodejsとnpmが必要なため、一時的にインストールし、あとでpurgeしています。
ENTRYPOINTをgulp、CMDを-hとすることによって
docker-compose run gulp
と実行すればgulp -hが実行され、
docker-compose run gulp <command>
とすればgulp <command>が実行されます。

npm

FROM debian:jessie

MAINTAINER "Kota Matsumoto" <kota1861@gmail.com>

RUN apt-get update -y
RUN apt-get install -y curl git
RUN curl -sL https://deb.nodesource.com/setup | bash --
RUN apt-get install -y nodejs
RUN npm update -g npm
RUN npm cache clean
RUN npm i -g n
RUN n stable
RUN apt-get purge -y nodejs npm

RUN mkdir -p /data/www
VOLUME ["/data"]
WORKDIR /data/www

ENTRYPOINT ["npm"]
CMD ["-h"]

構造としてはgulpとほぼ同じです。
完全に別にしていますが、このnpmのdockerfileをビルドしたものをどこかのレジストリにpushしておき、npmとgulpで同じimageをFROMに設定することでDRYにすることが可能です。

composer

FROM php:7.0.12

MAINTAINER "Kota Matsumoto" <kota1861@gmail.com>

WORKDIR /tmp

RUN apt-get update -y
RUN apt-get install -y git unzip
RUN curl -sS https://getcomposer.org/installer | php
RUN mv composer.phar /usr/local/bin/composer
RUN composer self-update
RUN composer global require hirak/prestissimo

RUN mkdir -p /data/www
VOLUME ["/data"]
WORKDIR /data/www

ENTRYPOINT ["composer"]
CMD ["--help"]

こちらはcomposerを使用するだけなので、使用するimageは純正のimage(fpmとか入っていない)を使っています。
composerをcurlコマンドで取得後、実行可能な場所に設置するのですが、このディレクトリはこのコンテナだけが参照できるので、他のサービスではcomposerを使用することはできません。
composerの各パッケージを並列にインストールできるようhirak/prestissimoをインストールしています。
composerの実行対象ディレクトリは/data/wwwですので、ここをworkdirとしています。
composerはキャッシュ機構があるので、複数人で開発をする場合は、都度composerの実行後コンテナをimageに固め、レジストリにpushすることで、各パッケージのインストール時間を軽減できます。

gulpと同様
ENTRYPOINTをcomposer、CMDを-hとすることによって
docker-compose run composer
と実行すればcomposer -hが実行され、
docker-compose run composer <command>
とすればcomposer <command>が実行されます。

使用方法

dockerディレクトリでdocker-composeコマンドを使用します。

# 各デーモン系コンテナの起動
docker-compose up -d

# laravelのインストール
docker-compose run --rm composer create-project laravel/laravel

# npmコマンドの実行(elixir等のインストール)
docker-compose run --rm npm install

# gulpでライブコーディング
docker-compose run --rm gulp watch

# composerパッケージのアップデート
docker-compose run --rm composer update

まとめ

このように各サービス、プロセスごとに分割することで、それぞれのサービスを独立して管理することができ、開発に集中することができます。
LaravelではhomesteadというVagrantで動くものを提供していますが、Docker for Mac等Dockerをローカルで使用できる環境が整ってきたので、起動スピードの早いDockerを使うのが何かと便利かとおもいます。

kotamat
roxx
人材紹介業むけプラットフォーム「agent bank」、リファレンスチェックサービス「back check」を運営。
https://roxx.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした