Windows Subsystem for Linux上でphp-fpmを動かしてみた
最近のWindows 10にはLinuxバイナリをそのまま動かすような仕組みが導入されています。これは Windows Subsystem for Linux (WSL) とか Bash on Ubuntu on Windows (BoW) などと呼ばれているもので、VM実行でなくWindowsネイティブでLinuxを動かすという意欲的な取り組みです。
この環境で最新版のPHPをソースコードからビルドし、アプリケーションサーバとして動作させてみました。
本稿執筆時点(2017年5月)ではWSL自体がまだ不安定な印象ですが、nginx+php-fpmを動作させることができました。以下はWindowsのlocalhost 80番ポートでPHPが動作している証拠画像です。「System」欄のunameの表示にMicrosoftという文字列が入っているのがオシャレですね。
以下、WSL上でnginx+php-fpmを動かすまでの手順を紹介します。
WSLのセットアップ
「Bash on Ubuntu on Windows - Installation Guide」に従ってセットアップします。
PHPのビルド
まずはWSL上でPHPをビルドしてみましょう。
コンパイル済みバイナリをaptでインストールしてもいいのですが、普通にビルドできる程度にWSLが安定してるのかな?という興味から自前ビルドしてみました。
まずは必要パッケージをインストールします。
$ sudo apt update $ sudo apt install build-essential libxml2-dev zlib1g-dev libcurl4-openssl-dev \ libjpeg62-dev libpng12-dev libmcrypt-dev libreadline-dev libtidy-dev \ libxslt1-dev libssl-dev libbz2-dev git autoconf
今回はphpenv+php-buildでPHPをビルドします。
$ curl -L https://raw.github.com/CHH/phpenv/master/bin/phpenv-install.sh | bash $ mkdir $HOME/.phpenv/plugins $ cd $HOME/.phpenv/plugins $ git clone https://github.com/php-build/php-build.git
下記の内容を .bashrc
に追記してシェルを再起動します。
PATH=$HOME/.phpenv/bin:$PATH eval "$(phpenv init -)"
あとはphpenv経由でPHPをビルドするだけです。
$ PHP_BUILD_EXTRA_MAKE_ARGUMENTS=-j4 phpenv install 7.1.4
ビルドにはかなり時間がかかるので注意してください。筆者の手元のマシン(Thinkpad X260、Intel Core i7 2.5GHz)で30分以上かかりました。同じビルドが12インチMacBook(Early 2016、Intel Core m5 1.2GHz)で10分を切ることを考えると、まだお仕事で使えるレベルではない印象です。今後のパフォーマンスチューニングに期待しましょう。
ちょっと遅いことを除けば、ビルド自体は正常に終了します。ここまでは普通のLinuxと大差ありません。
nginx+php-fpmの設定
つぎに、nginxをaptでインストールします。
$ sudo apt install nginx
設定ファイル /etc/nginx/sites-enabled/default
の設定のうち、下記部分のコメントアウトを外して有効化します。
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass 127.0.0.1:9000; }
nginxを再起動します。
$ sudo service nginx restart
php-fpmの方はデフォルトの設定ファイルをコピーしてそのまま使います。
$ cd $HOME/.phpenv/versions/7.1.4/etc/ $ cp php-fpm.conf.default php-fpm.conf $ cp php-fpm.d/www.conf.default php-fpm.d/www.conf
下記コマンドでphp-fpmを起動します。
$ $HOME/.phpenv/versions/7.1.4/sbin/php-fpm
ここで /var/www/phpinfo.php
などを設置すれば、nginx経由でphp-fpmを利用することができます。
ただし、この設定だと1秒に1回下記のエラーが出続けます。getsockopt(2) の実装がまだ不完全のようですね。
[01-May-2017 20:06:06] ERROR: failed to retrieve TCP_INFO for socket: Protocol not available (92) [01-May-2017 20:06:07] ERROR: failed to retrieve TCP_INFO for socket: Protocol not available (92) [01-May-2017 20:06:08] ERROR: failed to retrieve TCP_INFO for socket: Protocol not available (92)
TCPでのプロセス間通信に問題があるならunix domain socketにすればいいじゃない、と考えてunix domain socketも試してみたのですが、phpinfo()
の結果が途中で切れてしまうようです。こちらも実装が不完全なようで、16KB超のデータがうまく扱えないとか、そんな制限がありそうな挙動に見えました。TCPの方がまだ安定している状況だといえるでしょう。
まとめ
WSLはまだbeta版なので過度の期待をする方が悪いと言えばそうなのですが、まだ性能が出なかったり未実装のシステムコールもあったりで、お仕事で使えるようになる日は遠いかな、という印象を持ちました。
とはいえ、長期的に期待できる技術なのは間違いないところでしょう。さらなる安定と正式リリースが待ち遠しいですね。