suin.io

dinghyでPHP-FPM環境をDocker上に構築してみた

suin2016年7月24日

Dockerを開発に取り入れる場面が増えてきていると感じますが、それでもmacOS上に開発環境をDockerで作るとなると、Linux仮想マシンを自作したり、コンテナの名前解決のためにDNSサーバを立てたり、macOSとコンテナの間でファイル共有の仕組みを工夫したりと、導入までの準備が少なくありません。

こうした問題を一挙に解決してくれるのがdinghyです。dinghyはdocker-machineをラップする方法で、macOS向けに開発環境をDockerで素早く構築することを目的としたオープンソースプロダクトで、docker-machineには無かった次の機能を提供してくれます。

  • NFS: macOS側とコンテナ側のファイルを双方向に同期する。しかもVmwareやVirtualBoxのファイル共有より高速。
  • ファイルシステムイベント: ファイル更新を検知して動作するプログラム、例えば、webpackやglupが問題なく動く。
  • DNS: macOS側にDNSを立ててくれ、名前.dockerでDockerホストにアクセスできる。
  • nginx-proxy: Nginxベースのリバースプロキシを内部で使っていて、バーチャルホストやSSL(オレオレ証明書だが)も簡単に実現できる

dinghyのインストールと起動

dinghyが依存するパッケージをインストールします。

macOS上
brew install docker docker-compose docker-machine

次にdinghyをインストールします。

macOS上
brew tap codekitchen/dinghy
brew install dinghy

また、仮想マシンのハイパーバイザとしては、virtualboxvmwarexhyveparallelsが使えますが、ここではvirtualboxを例にするのでvirtualboxもインストールされている必要があります。

dinghyで仮想マシンを作成・起動します。

macOS上
dinghy create --provider virtualbox

しばらくして仮想マシンが起動したら、仮想マシン上のDocker APIをmacOSから使えるようにするために、環境変数を読み込みます。

macOS上
eval $(dinghy env)

PHP-FPM環境をdinghyを使って実現する

今回PHP-FPM化するアプリのファイル構成は次のようになります。htmlディレクトリはドキュメントルートです。nginx-config/default.conはNginxをPHP-FPMのリバースプロキシとして起動するための最低限の設定を記述したファイルです。docker-compose.ymlはnginxやphp-fpmのコンテナの起動方法を記述するファイルです。内容は後述します。

.
├── docker-compose.yml
├── html
│   ├── index.php
│   └── style.css
└── nginx-config
    └── default.conf

まず、ドキュメントルートに設置するファイルを作ります。今回は話をシンプルにするために、phpinfo()するだけのファイルと、静的ファイルの例としてstyle.cssの2つのファイルを用意します。

html/index.php
<?php
phpinfo();
html/style.css
/* dummy css */

次に、Nginxの設定ファイルを作ります。PHP-FPMのためのリバースプロキシとしての一般的な設定でOKですが、fastcgi_passの部分はサービス名:ポートを指定するようにします。サービス名は後述するdocker-compose.ymlで自分が定義するものになります。

server {
  listen 80;
  root /var/www/html;

  location / {
    try_files $uri /index.php$is_args$args;
  }

  location ~ \.php$ {
    fastcgi_pass  app:9000;
    fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include       fastcgi_params;
  }
}

最後にdocker-compose.ymlの中身です。イメージはDockerが公式で提供しているnginxとphpで十分ですが、その中でも容量の小さいAlpine Linuxを使いたいと思います。Debianがいい人は、Alpineにしなくても良いです。ここはおこのみで。

docker-compose.yml
nginx:
  image: nginx:alpine
  environment:
    VIRTUAL_HOST: php-app.docker # このサーバのバーチャルホスト名(nginx-proxy向け)
    VIRTUAL_PORT: 80 # 本コンテナは80と443が開いているので、80を指定する(nginx-proxy向け)
  volumes:
    - ./nginx-config:/etc/nginx/conf.d # FPMの設定をコンテナに読み取らせるためファイル共有を有効にする
    - .:/var/www # 静的ファイルをnginxが提供できるようにする
  links:
    - app # PHP-FPMコンテナとリンクする

app:
  image: php:7-fpm-alpine
  volumes:
    - .:/var/www

Dinghy固有の設定はenvironmentVIRTUAL_HOSTVIRTUAL_PORTです1VIRTUAL_HOSTにはmacOS側からどんなホスト名でアクセスしたいかを決めてその名前にします。ただし、ホスト名は.dockerで終わる必要があります。今回はhttp://php-app.dockerでアクセスできるよう、"php-app.docker"をホスト名とします。

VIRTUAL_PORTEXPOSEがひとつしかないDockerコンテナなら特に指定する必要はありませんが、公式のnginxイメージは80と443ポートが開いているので、nginx-proxyに443が代表ポートと誤解されないよう80を宣言します。

ここまでできたら、docker-composeでアプリを起動します。

docker-compose up -d

最後に、http://php-app.dockerするとindex.phpが実行され、http://php-app.docker/style.cssにアクセスするとstyle.cssの中身が表示されるのが分かるかと思います。

おわりに

macOS上で簡単にDocker開発環境が構築できるdinghyを使い、PHP-FPM環境を作ってみました。これまでのVagrant等2では面倒だった構築のステップがかなり省力化されたと感じたのではないでしょうか。


  1. 細かく言うとdinghyが内包するnginx-proxy向けの設定です。nginx-proxyはDockerでバーチャルホストを実現するためのリバースプロキシコンテナです。dinghyとは別にこれ単体で使うことも可能。 

  2. 最近ではDocker for Macの公開でmacOSとDockerの親和性に期待が高まっていますが、Docker for Macはオープンソースになっておらず、ファイルシステムの共有・DNS・バーチャルホスト名などの情報もまだまだ少ない段階と思います。dinghyコミュニティでもDocker for MacをDinghyの代替手段として検討する話題も上がっていますが、結論は今日現在出ておりません。Docker for Macが決定版になるまではdinghyを使うほうが良いのではと考えております。 

RELATED POSTS