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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
├── 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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

1
2
3
4
5
6
7
FROM debian:jessie

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

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

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

fpm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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のコンテナに向けてリバースプロキシをするために、サーバーのホスト名・ポート番号を下記のように指定する必要があるのですが

1
2
3
4
5
6
http {
    upstream phpfpm_backend {
        server fpm:9000;
    }
    ...
}

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

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

1
2
    access_log /data/logs/access.log;
    error_log /data/logs/error.log warn;

gulp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
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コマンドを使用します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 各デーモン系コンテナの起動
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を使うのが何かと便利かとおもいます。