Ubuntu16.10へDockerをインストールしてPHPのビルトインサーバーを利用するには

Ubuntu16.10へDockerをインストールしてPHPのビルトインサーバーを利用できるようにしたときのメモ。

Dockerのインストール

Get Docker for Ubuntu – Docker」にある通り。apt-key の確認のところだけ、失敗なりエラーがでたら、本家を確認した方がいい。

$ sudo apt-get update
$ sudo apt-get install \
    curl \
    linux-image-extra-$(uname -r) \
    linux-image-extra-virtual
$ sudo apt-get -y install \
    apt-transport-https \
    ca-certificates
$ curl -s http://yum.dockerproject.org/gpg | sudo apt-key add -
$ apt-key fingerprint 58118E89F3A912897C070ADBF76221572C52609D
$ sudo add-apt-repository \
   "deb https://apt.dockerproject.org/repo/ \
    ubuntu-$(lsb_release -cs) \
    main"
$ sudo apt-get update
$ sudo apt-get -y install docker-engine
$ sudo docker run hello-world

ユーザーをdockerグループへ追加

ユーザーがdockerコマンドを実行できるようにします。一度ログアウトしてログインをしなおします。

$ sudo usermod -aG docker ${USER}

PHPのDockerイメージ

GitHub – docker-library/php: Docker Official Image packaging for PHPにPHPのDocker公式イメージがある。

あらかじめcreate-php7_dockerfile_router-php.shを作成しておきます。

cat << EOF > Dockerfile 
FROM php:7.0-cli
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
CMD [ "php", "./router.php" ]

EOF
cat << EOF > router.php
<?php
// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
    return false;    // リクエストされたリソースをそのままの形式で扱います。
} else { 
    echo "<p>Welcome to PHP</p>";
}
?>

EOF

下記のようにDockerコンテナのルートとするphp7ディレクトリー用意して、Dockerfileとrouter.phpを作成します。router.phpは「PHP: ビルトインウェブサーバー – Manual」で紹介されていたものです。

$ mkdir php7
$ cd php7/
$ sh ../create-php7_dockerfile_router-php.sh

Dockerコンテナのビルドと実行

Dockerコンテナのビルドと実行は次の通り。

$ docker build -t php7-app .
$ docker run -it --rm --name php7-running-app php7-app
<p>Welcome to PHP</p>

php:7.0-cliの利用

PHPを単体で実行するにはphp:7.0-cliのイメージを使います。cmdに実行したいコマンドを指定します。

$ cmd="php router.php"
$ docker run -it --rm --name php7-running-app \
  -v "$PWD":/usr/src/myapp \
  -w /usr/src/myapp \
  php:7.0-cli \
  ${cmd}

PHPのビルトインサーバーの利用

PHPのビルトインサーバーを起動するには、cmdに次のように指定します。また、「-p 8000:8000」でDockerホストのポート8000からDockerコンテナの8000へのポート転送をします。php7ディレクトリーにあるスタティックファイルへのアクセスができるようになります。

$ cmd="php -S 0.0.0.0:8000"
$ docker run -it --rm --name php7-running-app \
  -p 8000:8000 \
  -v "$PWD":/usr/src/myapp \
  -w /usr/src/myapp \
  php:7.0-cli \
  ${cmd}

例えばphp7/sample.jpgファイルを用意してから、Dockerホストのマシンのポート8000へWebブラウザからアクセスします。DockerホストマシンからWebブラウザからアクセスする場合は「http://localhost:8000/sample.jpg」です。これでsample.jpgが表示されます。Ctrl+Cで停止します。

router.phpの利用

router.phpを動かすと、画像ファイル以外のURLは「Welcome to PHP」と表示されます。たとえば「http://localhost:8000/index.html」とすると、Welcome PHPと表示されます。

$ cmd="php -S 0.0.0.0:8000 router.php"

CORS対応のテストサーバーとして起動

手元にPHPの環境がなかったので、ようやくたどりつきましたが、PHP7でCORS対応のテストサーバーを用意するには、下記のようなPHPファイルを用意して、router.phpと同様にcmdへ指定してからdockerコンテナを使えば良いです。ここではjsonファイルはCORS対応のものとしてレスポンスを返しています。

<?php
$path = pathinfo($_SERVER["SCRIPT_FILENAME"]);
if ($path["extension"] == "json") {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Request-Method: *');
    header('Access-Control-Allow-Methods: OPTIONS, GET');
    header('Access-Control-Allow-Headers: *');
    header('Content-Type: application/json');
    readfile($_SERVER["SCRIPT_FILENAME"]);
} else {
    return false;
}
?>

例えば、次のような php7/name.json ファイルを用意して、「http://localhost:8000/name.json」へアクセスしてみるといいでしょう。

{ "name":"Angular2 JSON" }

レスポンスヘッダの確認

Webブラウザの開発ツールでレスポンスヘッダの確認はできます。次のようにtelnetでも手軽に確認できます。 [Enter]と書いてある行が入力行です。

$ telnet localhost 8000 [Enter]
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /name.json [Enter]

HTTP/0.9 200 OK
Connection: close
X-Powered-By: PHP/7.0.14
Access-Control-Allow-Origin: *
Access-Control-Request-Method: *
Access-Control-Allow-Methods: OPTIONS, GET
Access-Control-Allow-Headers: *
Content-Type: application/json

{ "name":"Angular2 JSON" }

Connection closed by foreign host.
同じタグの記事: Docker
同じタグの記事: PHP
同じタグの記事: PHP7
同じタグの記事: Ubuntu
同じカテゴリの記事: Linux
関連書籍: PHP