Docker + Nginx + PHP-FPM なら40秒くらいで環境を準備できる docker-compose が楽しくなってきました。


掲題のアイテムをつかっての環境づくりなので、DBもないし、完全に docker の勉強です。でもこれらの組み合わせのサンプルをいろいろ Web で漁ったのですが、なぜか動かなく..。なんとか動くものができたので、投稿になります。

GitHub

こちらにまとめましたので、結論だけ知りたいかたは、こちらからどうぞ。

mochizukikotaro/docker-nginx-phpfpm - branch:simple

できたもの

  • docker
  • nginx
  • php-fpm

な環境を docker-compose を用いて簡単に作れるようになりました。

僕は Mac ユーザーで、それ前提ですが、Doceker for Mac が入っていれば以下のコマンドで、phpinfo() に辿りつけます。

開始コマンド

$ git clone [email protected]:mochizukikotaro/docker-nginx-phpfpm.git
$ cd docker-nginx-phpfpm.git
$ docker-compose up

上の 3 つのコマンドで、localhost:8080 にアクセスすると下の画面に辿りつけます。

あとかづけコマンド

docker-compose up でコンテナが立ち上がっていますが、勉強なので削除もしっかりしておきたいところです。
(下のコードの piyo は僕のディレクトリ名がそうなっているだけなので、あまり気にしないでください。)

# プロセス確認
$ docker-compose ps
   Name                 Command               State     Ports
-------------------------------------------------------------
piyo_php_1   docker-php-entrypoint php-fpm   Exit 137
piyo_web_1   nginx -g daemon off;            Exit 137

# コンテナ削除
$ docker-compose down
Removing piyo_web_1 ... done
Removing piyo_php_1 ... done

ソースコードの紹介

コードもできるだけシンプルな構成にしております。

$ tree
.
├── Dockerfile
├── README.md
├── code
│   └── index.php
├── docker-compose.yml
└── site.conf

これだけなので、あまり難しいことはないと思います。

docker-compose.yml
version: '3'
services:
  web:
      build: ./
      ports:
          - "8080:80"
      depends_on:
          - php
  php:
      image: php:7-fpm
      volumes:
          - ./code:/code
site.conf
server {
    index index.php index.html;
    server_name localhost;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /code;

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

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
code/index.php
<?php
echo phpinfo();

全ソースはこちら

以上です。
ここまでの話は、シンプルでわかりやすいと思います。

考察とか、解説とか

その1. links

最初に docker-compose.yml をつくったときは、下のように links: をつかっていました。

docker-compose.yml
web:
    # 略
    links:
        - php
    # 略

links: を設定することで、nginx のコンテナの /etc/hosts にサービス情報が追加されます。これにより、site.conf に以下のように記載することができます。

fastcgi_pass php:9000;

実際に hosts の情報を確認してみると以下のようになっていました。

# まずは、nginx コンテナに入る
# ぼくは git clone *** piyo でディレクトリ名指定しているので、以下のようなカンジです。

# コンテナ名を確認
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                           NAMES
6ee2fb5c8aaa        nginx:latest        "nginx -g 'daemon ..."   6 minutes ago       Up 6 minutes        443/tcp, 0.0.0.0:8080->80/tcp   piyo_web_1
9b8ed908d621        php:7-fpm           "docker-php-entryp..."   6 minutes ago       Up 6 minutes        9000/tcp                        piyo_php_1

# 中に入る
$ docker exec -it piyo_web_1 bash
root@6ee2fb5c8aaa:/#


# 入ったあとに cat 
root@6ee2fb5c8aaa:/# cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  php 9b8ed908d621 piyo_php_1 # ちゃんと追加されてました。
172.17.0.2  php_1 9b8ed908d621 piyo_php_1
172.17.0.2  piyo_php_1 9b8ed908d621
172.17.0.3  6ee2fb5c8aaa

その2. links: の代わりに depends_on: を使うと

ngix コンテナの hosts に php とは書かれていませんでした。

$ docker ps
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS              PORTS                           NAMES
14487c92de8b        dockernginxphpfpm_web   "nginx -g 'daemon ..."   10 hours ago        Up 10 hours         443/tcp, 0.0.0.0:8080->80/tcp   dockernginxphpfpm_web_1
ba2d44f70e13        php:7-fpm               "docker-php-entryp..."   10 hours ago        Up 10 hours         9000/tcp                        dockernginxphpfpm_php_1

$ docker exec -ti dockernginxphpfpm_web_1 bash
root@14487c92de8b:/# cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.21.0.3  14487c92de8b # これが使われています。

TODO:
あれ、nginx の設定ファイル site.conf の fastcgi_pass php:9000; はうごくのか.... links のおかげで hosts にかかれて動くと思っていたんですが。どういう仕組なんだろう。..勉強します。

少ししらべた結果 :
nginx コンテナの /etc/resolv.conf に nameserver が指定してありますので、DNS がうごきます。実際、 ping php に対して名前解決はされていました。

$ docker exec -it dockernginxphpfpm_web_1 ping php
PING php (172.21.0.2): 56 data bytes
64 bytes from 172.21.0.2: icmp_seq=0 ttl=64 time=0.102 ms
64 bytes from 172.21.0.2: icmp_seq=1 ttl=64 time=0.216 ms

その3. nginx/conf.d/default.conf を上書きしています

こちらに nginx の設定ファイル についてかきましたが、デフォルトで、default.conf がいます。それで、最初は以下のようにしていました。

docker-compose.yml
# before
- ./site.conf:/etc/nginx/conf.d/site.conf

# after ( default.conf を上書きます)
- ./site.conf:/etc/nginx/conf.d/default.conf

beforeの状態だと、default の location が効いてしまい、うまくいきませんでした。

( nginx についても勉強不足なので、目下勉強中でございます。)

以上でございます。ありがとうございました。