75
71

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

周回遅れのDocker 2: Docker による PHP サーバ

Last updated at Posted at 2015-07-04

Docker 公式の PHP イメージを使って Web サーバに相当するコンテナを作ってみる。今回のコンテナ例では立ち上げると phpinfo() を出力する PHP Web サーバを提供することとする。

また -v (--volume) オプションを使って、ローカルディスクの領域を Web サーバのドキュメントルートとしてマウントした際の挙動もあわせて確認する。

なお以下の例で実行している docker コマンドは、docker-machine で作られたホストに対して行っており、事前に docker-machine env による環境変数が設定済みの状態。

Apache + PHP

コンテナイメージの準備

まず PHP の phpinfo() を出力するファイルを用意。

public/info.php
<?php
phpinfo();

続けて image ビルドのための Dockerfile を用意。ここでは、 Apache モジュールが同梱された PHP コンテナイメージをベースとして使う。
あわせて、先ほどの PHP ファイルをコンテナイメージに同梱するよう COPY を使ってローカルファイルをコンテナに含めるようにする。コピー先は、ベースとなるコンテナが提供している仕様に基づくディレクトリとする。すなわち今回利用しているベースコンテナの php:apache の Apache がドキュメントルートとして利用しているディレクトリで、ここでは /var/www/html となっている。

Dockerfile
FROM php:apache
COPY ./public/info.php /var/www/html/

docker build コマンドを使って、新たな自前 Docker イメージを作成する。
Dockerfile で定義した利用コンテナイメージのダウンロードが行われ、それを基にして新規イメージが作られる。

$ docker build -t sandbox-phpinfo-apache .

docker images コマンドを実行すると、先ほど作った新規イメージが利用可能な状態であることがわかる。

$ docker images

REPOSITORY               TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
sandbox-phpinfo-apache   latest              5cfc1b74c92a        42 seconds ago      481 MB
php                      5.6-apache          385019d6807e        12 days ago         481 MB

docker run コマンドでこの自前 Docker イメージからコンテナを実行する。
-p オプションはポートフォワード設定で、Docker ホストへのアクセスに対してコンテナへ流す設定を行っている。

$ docker run --name phpinfo -p 80:80 -d sandbox-phpinfo-apache
fe055eccf5d24cc1fa5cec7940a6e619480dc6b091e0b83a8f0217007a795de6

動作確認

起動した Apache + PHP コンテナイメージに対してアクセスしてみる。
まずは Docker ホストの IP アドレスを docker-machine ip コマンドでチェック。

$ docker-machine ip dev

192.168.99.100

得られたアドレスを使って Docker ホストへブラウザでルートアクセスすると、phpinfo() が表示される。

スクリーンショット 2015-06-29 23.52.58.png

ローカルディレクトリをマウントして Web サーバを動かす

続けて、ローカルの public ディレクトリを先ほどのコンテナの Apache ドキュメントルートとしてマウントして動かしてみる。

ローカルには先ほどの phpinfo() 出力プログラムとは違う内容のものを用意。

public/index.php
<?php
echo "Hello, world: ", time();

先ほどのコンテナを一旦止めて、-v オプションで public ディレクトリをドキュメントルートへマウントする。

$ docker ps
CONTAINER ID        IMAGE                    COMMAND                CREATED             STATUS              PORTS                NAMES
fe055eccf5d2        sandbox-phpinfo-apache   "apache2-foreground"   7 minutes ago       Up 7 minutes        0.0.0.0:80->80/tcp   phpinfo

$ docker stop phpinfo
phpinfo

$ docker run --name phpinfo2 -v /path/to/sandbox-docker-phpinfo-apache/public:/var/www/html -p 80:80 -d sandbox-phpinfo-apache
40b99a767cbc2fbddb90d22fdc9e70296401cbce625c6133c355b455bbb2f0c7

再びブラウザでルートアクセスすると、今度は phpinfo() ではなく、public/index.php に書かれた Hello, world プログラムの結果が表示される。また、/info.php にアクセスすると phpinfo() が表示される。以上より、マウントした public ディレクトリがコンテナ内 Apache のドキュメントルートになって稼働していることがわかる。

Nginx + PHP-FPM

続いてもう1つ PHP サーバを動かすスタイルとしてよく見られる Nginx と PHP-FPM を組み合わせたサーバを Docker で作ってみる。ここでは、Nginx コンテナと PHP-FPM コンテナの2つを用意して、Nginx コンテナからの Proxy アクセスで PHP アプリケーションが利用できるようにする。

PHP-FPM コンテナ

php-fpm の Docker イメージをベースにしてコンテナを作成。あわせて phpinfo() を表示する PHP ファイルを先ほどの Apache のときと同じようにコピーする。

phpfpm/Dockerfile
FROM php:fpm
COPY index.php /var/www/html/
phpfpm/index.php
<?php
phpinfo();

イメージの作成とコンテナ起動。ここでは phpfpm という名称で起動した。
php:fpm の Docker コンテナな PHP-FPM を tcp:9000 で待ち受けするとのことだが、Nginx からの Proxy アクセスのみを考慮しているので、Docker 起動時のポートマッピングオプションは必要なしになる。

$ docker build -t sandbox-phpinfo-phpfpm ./phpfpm
$ docker run --name phpfpm -d sandbox-phpinfo-phpfpm

Nginx コンテナ

Nginx イメージ を使う。
PHP-FPM への Proxy アクセスのためのサーバ設定ファイルを用意して、コンテナをビルドする際に設定ファイルディレクトリへファイルを埋め込む。

FROM nginx
ADD server.conf /etc/nginx/conf.d/server.conf

Proxy 設定ファイルは以下のとおり。
ここでポイントなのが、Proxy 先となる PHP-FPM のホストを 127.0.0.1 などの IP, hostname ではなく、Docker のコンテナ間接続のための機構である link オプションによるエイリアス名を指定することになる。ここでは php という名称にした。 ("fastcgi_pass php:9000;" の箇所)

nginx/server.conf
server {
    listen 80 default;
    server_name _;
    root /var/www/html;
    index index.php index.html index.htm;
    charset utf-8;

    access_log off;
    error_log off;

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

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

イメージの作成とコンテナ起動。
前述したコンテナ間接続のため、link オプションで <コンテナ名>:<エイリアス名> を指定する。phpfpm コンテナに対して Nginx 設定ファイル内で php というエイリアス名を使っているので、 --link phpfpm:php となる。

$ docker build -t sandbox-phpinfo-nginx ./nginx
$ docker run --name nginx -p 80:80 --link phpfpm:php -d sandbox-phpinfo-nginx

動作確認

Apache + PHP の時と同様、Docker ホストへブラウザでルートアクセスすると、PHP-FPM による phpinfo() が表示される。

スクリーンショット 2015-06-30 22.50.40.png

サンプルソース

今回利用したサンプルソース。

75
71
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75
71

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?