PHPで書いたWebページをVagrant+Ubuntu+Nginxで複数デバイスから閲覧する
PHPとは相性が悪い、というのがプログラミング入門初期からの実感で、これまで「おー、やった!いいじゃんPHP!!」みたいに思ったことは一度もありませんでした。
しかし昨年の後半、いろんな成り行きからもう頑張るしかない・・みたいな状況に追い込まれまして(たぶんそれについては別記事で)、少し本腰を入れてというか、時間をかけて対応しましたら、ようやく「はあ〜、できた」みたいになったので、ここにメモしておきたいと思います。
ちなみに、この現象と解消、以前から何度かくり返してはいたのですが、そのつど「あれって、一回できたはずだけど、どうやるんだっけ? もう忘れちゃったよ・・」というくり返しでもあったので、今度こそちゃんと記録しておく、というのもあります。
あとは、その以前に辿りついた解決法というのも、結局いろいろイジっているうちになんか知らんけど出来てしまった、みたいな感じだったりして、その意味でも再現しづらかったので今度こそ(略)という感じでもあります。
やりたいこと
記事タイトルにもバリッと書きましたが、今回の目標は
PHPで書いたWebページをローカルネットワーク内で複数ブラウザから閲覧する!
というものです。
これはメインのPCのブラウザから見るのはもちろんですが、スマホでも見れるとか、離れた部屋の別マシンでも見れるとか、そういう状態を指しています。
で、今回はそのWebページ自体は重要ではないので、以下のコードだけを記した hello.php というファイルを作成し、
<?php echo '<p>Hello, PHP!</p>'; ?>
これを Vagrant の共有フォルダに置いて閲覧できるようにする、としたいと思います。
その閲覧時の手順としては、最初にローカルサーバ上のトップページである index.html に入って、そこから張られている hello.php のリンクをクリックしたらそのページに移動して「Hello, PHP!」を見る。という感じで行ってみます。
先にその結論というか、成功した状態を見てみましょう。
はい、左上に控えめに「Hello, PHP!」と表示されました。これができればOKです。
環境の前提
記事タイトルにも書きましたが、今回はVagrantでUbuntuを起動して、その中に入れたNginxでサーバを立てます。
Nginxを起動してHTMLのトップページを見られるようにするまでの段取りは、少し前に書いた以下の記事のママですので、今回は割愛します。ご興味おありの方は、そちらをどうぞ。
余談ですが、今回のUbuntuは12.04ですが、このバージョン番号を調べるのに何気に時間がかかりました。どうやったら正確なバージョンを調べられるのだろう? と。
もちろん、ちょっとググればいろんな方法が出てくるのですが、どれも不要な情報があれこれと一緒に表示されてしまって、読み解きにそれなりにコストがかかるなあ、と。
しかしこれ、単にUbuntuに最初にログインしたとき、つまり「vagrant ssh」で入ったときに、このように出てくるんですね。
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)
完全に見落としていて、たぶんトータル20〜30分ぐらい費やしました。いやほんとに余談ですが・・。
さらにちなみに、今この手順でこのUbuntuを立ち上げると、14.04にせよ、と以下のように出てくるのですが、
* Documentation: https://help.ubuntu.com/ New release '14.04.5 LTS' available. Run 'do-release-upgrade' to upgrade to it.
今回は無視しています。
PHPファイルが無限にダウンロードされる問題
では、ここから本題です。ひとまずトップページが見えるところまで設定して、目的の hello.php を開こうとすると、こんな感じで・・
ページ移動すらせず、とりあえずファイルがダウンロードされてしまいます。何回クリックしても、何回でもダウンロードされます。(当然ですが)
これは今回の最初の難関ですが、同時にこの後どれだけいろんなことを試してもなかなか解消されない最大の難関でもありました。実際、ぼくのダウンロードフォルダはこの hello.php が大量に溜まってしまい、ひどい時はファイル名が hello.php(17) とかになってましたね・・。
PHPをインストールする
さて、この時点では何が何やら、原因のゲの字もわかりません。
ということで、とりあえずググりまくって最初に役立った記事はこちらでした。
とくに、ここで書かれているこのコマンド。
$ dpkg -l |grep php | awk '{print $2}'
リンク先では、これによってインストール済みのPHP関連パッケージを見つける、みたいな感じでこのコマンドが紹介されていましたが、ぼくがこれを打ってどうなったかというと、
はい。何も出ないですね。なんだろう、コマンド自体間違ってるのかな? と思ってPHPのところをPerlにしてみると、
ちゃんと出てきます。つまり、PHP自体まったく入ってなかったんですね。これには驚きました。なんだ、そもそもPHP入ってないんかい! という。いやあ、PHPってめっちゃメジャーな言語なので、当然どこにでも入っているものだという思い込みがありました。
さて、じゃあPHP入れようよ、簡単でしょ? という感じなんですが、これはこれで逆にあちこちに情報があふれすぎていて、今回ぼくが求める最小限のインストール方法ってどうしたらいいのか、精査するのがきわめて大変でした。
結論的には、以下のブログ記事の冒頭で紹介されていた、
最低限のラインナップ。
$ sudo apt-get install -y php5 php5-fpm
これだけにしておきました。実際にちゃんと使おう、PHP書こう、という時はこれでは足りないのかもしれないですが、今回はオプション的な情報が入るとかえって煩雑になるので。
設定ファイルを編集
さてしかし、PHPのインストールが完了してもまだファイルのダウンロードは止まりません。クリックすればしただけPHPファイルがダウンロードされてきます。
そこで、次にどうしたかというと、上記の同記事で紹介されていた以下の設定ファイルを書き換えます。
$ sudo vi /etc/nginx/sites-available/default
ファイルを開いたら、以下の箇所で5行分コメントアウトを解除します。(オフだったのをオンにする)
location ~ \.php$ { #← 解除 # fastcgi_split_path_info ^(.+\.php)(/.+)$; # # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini # # # With php5-cgi alone: # fastcgi_pass 127.0.0.1:9000; # # With php5-fpm: # # ↓ 以下4行解除 fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; }
なお、この際、リンク先の解説では最初の行の拡張子部分にもう少し手を入れるように教えてくれていますが、前述の通り、これも今回の目的とは少しずれるのでその点は反映していません。
ここまでやってからNginxを再起動すると、
$ sudo service nginx restart
はい、やりました。ついに hello.php に移動してくれました。なんか、違うのが出ていますが・・。
502 Bad Gateway から逃れる
ファイルをダウンロードしなくなったのは大きな前進です。このまま記事を終えても良いぐらいですが、それで納得するのはぼくぐらいでしょうから、もう少し頑張ります。
現在画面に出ている「502 Bad Gateway」を消す方法については、ここまでの参考記事ではとくに言及がありませんでした。
そこでまたいろいろググりまして、以下の記事を見つけました。
これはこれで何というか、膨大な情報があふれていて、詳しい人にとっては有用なリファレンスかもしれないのですが、ぼくにとっては「こん中のどれを参考にすればええんや!」という感じで途方に暮れましたが、とにかく一つひとつそれらしいのを試して、結論的には以下の設定ファイルを編集すれば良いことがわかりました。
$ sudo vi /etc/php5/fpm/pool.d/www.conf
これを開いて、まず以下の2行のコメントアウトを解除します。
listen.owner = www-data listen.group = www-data
そして、その近くに(じゃなくてもいいとは思いますが)以下を追加。
listen = /var/run/php5-fpm.sock
はい。で、php5-fpm を再起動。
$ sudo service php5-fpm restart
で、どうなるかと言うと・・
や、やりました!
iPhoneのブラウザからも見れます。(9秒の動画)
雑感
ということで、長きにわたるPHPとの戦いにも終止符が打たれ、ぼくも晴れてPHPerの仲間入り・・ができたかはわかりませんが、個人的にはひとつの大きな達成でした。
とくにあの、何回試してもとりあえずファイルがダウンロードされるタイムリープ世界から解放されたのは、本当になんというか、よかったです。
ちなみに、ちょっとしたローカルサーバ利用だったらべつにそんなことしなくても、ビルトインサーバ使えばいいんだよ、と言われてしまうかもしれないのですが、それは大丈夫です、わかっています、ということで。
何しろぼくは以下のムックで、うずらさんのPHP記事、付箋ペタペタ張りながらそれなりに読み込みましたから。
Webアプリエンジニア養成読本[しくみ、開発、環境構築・運用…全体像を最新知識で最初から! ] (Software Design plus)
- 作者: 和田裕介,石田絢一(uzulla),すがわらまさのり,斎藤祐一郎
- 出版社/メーカー: 技術評論社
- 発売日: 2014/04/15
- メディア: 大型本
- この商品を含むブログ (5件) を見る
ビルトインサーバについては、その中でもちゃんと取り上げられているのです。
なので問題は、どちらかと言うと「同ネットワーク内にいる他のデバイスからも見れるようにしたい」という方ですね。その欲求に応えようとすると、なかなか茨の道だったな・・と。
また正直なところ、お読み頂いてわかったかもしれないですが、設定ファイルを書き換えた辺りについては、自分で何をやっているのかまったくわかっていません。この辺、どういう部分をどのように、なぜ書き換えるのか、ということを解読していけると、もっと面白くなるかなあとも思っています。
ともあれ、この記事によって、少なくとも未来の自分はもうPHPの同件で時間を浪費することがない(あるいはその時間を最小化できる)だろうと思っています。おつかれさまでした。
追記
本文でも勝手に登場させて頂いてしまいましたうずらさんから、大変勉強になるコメントを次々と頂いたので、以下にまとめさせて頂きます。
*Twitter、あとから掘り起こすのメチャ大変なのが目に見えていたのでとにかく今のうちに・・と。
*togetter使う手も考えましたが、あれってあまり相性が良くないというか、今まで満足に使えた試しがないのでこちらで。
*途中でかたついさんがしれっと入っていますが、うずらさんが一連のツイートの間にRTされていたものです。
わかる…解決策はnginxをつかわずにApacheをつかう事で、他のPerl/Plackとかみたいにしたいならnginx+PHPはあきらめて、nginx+Apache(+mod_php)という構成にすることや(この問題の8割くらい… https://t.co/3bIN6EOfVY
— うずら (@uzulla) January 6, 2019
fastcgiというやつ本当に難しいし、わかっている人のnginx config見てみたい。
— うずら (@uzulla) January 6, 2019
細かく言えば、fastCGIで、mod_php(やbuiltin server)と同じ挙動にする!というのが相当に難しい。
— うずら (@uzulla) January 6, 2019
「俺は何年でもプロダクションで使えるhttpdがPHPに入ってほしいと言い続けるマンだ!!」(こじらせた結果、大統一などと言い出したり、非同期などに詳しくなる)
— うずら (@uzulla) January 6, 2019
正直なところ「Apache?それってPHPにhttpdを喋らせたり、ワーカーを管理するためのプラグインだよね?」という気分もある。
— うずら (@uzulla) January 6, 2019
httpdを喋らせるとは???
— うずら (@uzulla) January 6, 2019
個人的に言えばh2oでも相当すっきりPHPを使う事ができますが、世の中の案件の多くは複雑なrewriteや、.htaccessというやつがどうしても必要なレガいコードの案件もあり、なかなかむずかしい…。
— うずら (@uzulla) January 6, 2019
そんなことがあるのか分からないけど、もしPHPの新規案件があるならFastCGIを使うのがおすすめです。理由は.htaccessとかrewriteとかが使えなくなるからです。
— 低気圧 (@catatsuy) January 6, 2019
もともと別言語(のfastCGIワーカー)で構成されたシステムで組まれていた結果、なし崩しでapache+mod_fcgidという地獄もあるのでまあfastCGIならレガくないということではない(が、そこまでの案件を引くラックは普通無いだろう)
— うずら (@uzulla) January 6, 2019
「結局mod_perlが最強だったんですよ」という意見がきた。
— うずら (@uzulla) January 6, 2019
うずらさん、最高です。
追記2
Twitterにて、こちらのご意見も頂きました。
PHP5.6は2018年内でサポート終了してしまったので… https://t.co/sytUr7P8xT
— たくみぶー (@Takumiboo) January 7, 2019
な、なるほど・・まったく知らなかったのですが、であれば7を入れる前提で考えた方がより汎用的な方法・情報になりそうですね。
今回の場合、一応ローカル利用特化&最低限のセットで、ということだったので5.6でも大きな問題はないと思いますが、サポートが終わってしまうなら個人的にも新しい方を入れられるようにしておきたいな、と。
ということで、次に同じようなことをやるときには、PHPインストールのくだりで7系(というかなるべく最新の)を入れる方向で調べ直し&トライし直してみたいと思います。