WordPress on Nginx on Windows。その1

追記(2019/04/13): Windows10でNginx+MariaDB+Wordpressをインストールする。その1に書き直しました。

システムの更新に伴って、もう数ヶ月も自宅サーバのブログが動いてません。いろいろ試してうまくいかないのでどうしようかと思ってるんですが、とりあえず一時退避でこちらのブログを使っています。

なぜそんなことになったかというと、まずプラットフォームの NetBSD が 8.0 をリリースしたのでアップグレードし、さらに PHP での MySQL サポートをこれまでの mysql ドライバが非推奨になり、mysqli ドライバに切り替わったことで DB への接続が変わってしまい、また Apache も 2.4系で設定が変わったという複合的な要因があったためで。

もういっそ Nginx にしてしまおうか、それなら uWSGI も使えるし、ブログは WordPress から Mezzanine にお引越しすればいいか、と考えたのですが、うちのサーバでは Perl CGI や mailman なども動いていて、なかなかめんどくさい。

全部 Nginx でできればいいんですが、PHP に関しては FastCGI にするか、uWSGI の Emperor モードにするかも悩ましいところですし、Perl CGI に至っては「もしかしてこれは Apache に処理させて、Nginx に proxy させるのが一番なのでは…」などと思い始める始末。古い技術に引きずられてしまっています。

ただ、WordPress にはこれまで書きまくった大量のエントリがあって、実はちょくちょく参照したい。データベースの方は dump してあるんですが、そのままではテキストエディタで読み込んでも使えない(1行が長すぎるなど)のため、ローカルに MariaDB をインストールして読み込ませました。そこに HeidiSQL を使ってクエリを飛ばして検索しているんですが、どうにも使いづらい。なのでいっそ、暫定的にローカルブログにしてしまって、ブラウザからアクセスするほうがいいかと思ったのがきっかけです。

その裏では新しく Manjaro Linux を使ってサーバを置き換えようかと準備は進めているのですが…。ところで記法は Nginx なんでしょうか、nginx なんでしょうか。


閑話休題。

Apache はモジュールの管理などいろいろと無理しているところもあり、設定も複雑化してきているので「管理で楽をしたい」というならば Nginx のほうがよさそうな感じです。
そうしたことを見据え、さらには慣れておきたいということもあって今回は Nginx を動かし、その上で WordPress をサーブさせるという方向でいじってみます。
実はすでに MariaDB はインストールされているため、そのへんはここでは触れません。

Nginx のインストール

まずはNginxのインストールです。一応 Cygwin64 などは使っているのですが、そこらへんは今回あまり関係ありません。
Nginx のサイトから、ダウンロードページに飛んで、Mainline のnginx/Windows-1.15.5をダウンロードします。
これは ZIP ファイルになっていますので、ダウンロードしたら展開し、いつもどおり c:\Apps\Nginx 以下に配置します。

そうしたら何もせずにいきなり nginx.exe をクリックすると、Nginxが常駐しサービスが始まります。ポート80を開くので Windows ファイアウォールの警告が出ますが、これは OK で先に進めます。あくまでデフォルト状態なので、コンテンツは Welcome メッセージだけですが、ブラウザで http://127.0.0.1/ にアクセスすると "Welcome to nginx!" というメッセージが表示されます。

PHPのインストール

Nginx が動いたらPHPをインストールします。PHPのダウンロードページに飛ぶとWindows用のリンクがあるので、そこを開きます。そこには64/32bit、Thread Safe/Non Thread Safe という形で4つのリンクがありますが、こちらの環境は Windows 10 64bit なので 64bit の Non Thread Safe 版をダウンロードします。
Thread Safe と Non Thread Safe のどちらを選ぶべばよいかは、PHP の FAQ に書かれています。

==
What does thread safety mean when downloading PHP?
Thread Safety means that binary can work in a multithreaded webserver context, such as Apache 2 on Windows. Thread Safety works by creating a local storage copy in each thread, so that the data won't collide with another thread.

So what do I choose? If you choose to run PHP as a CGI binary, then you won't need thread safety, because the binary is invoked at each request. For multithreaded webservers, such as IIS5 and IIS6, you should use the threaded version of PHP.

PHPをダウンロードする際に、thread safetyとは何を意味していますか?
thread safety は、たとえば Windows 上の Apache2 のようなマルチスレッドの Web サーバ環境で動作できるバイナリのことです。Thread Safety はそれぞれのスレッドに対してローカルなストレージコピーを作成することで、他のスレッドとデータの衝突が起きないように動作します。
それではどちらを選べばよいか? もしも PHP を CGI バイナリとして走らせるのであれば、thread safety である必要はありません。なぜならバイナリはリクエストごとに起動されるからです。IIS5 や IIS6 のようなマルチスレッド Web サーバを使用するのなら、thread safe な PHP を使うべきです。
==

ということで、FastCGI を使う場合には一番上にあるNon Thread Safeを選べばよいでしょう。
さて、ダウンロードした PHP はこれもまた ZIP ファイルなので、展開して同じように c:\Apps\PHP に置きます。あまりルートディレクトリがごちゃごちゃするのは好きではないので。
配置したら、環境変数を設定します。



一旦システム環境変数に PHPPATH という名前で環境変数を作成し、それを PATH に参照させます。


自分の場合は、長い文字列のなかでパスのだぶりを見つけるのがとても面倒なのでこうしています。
特に「特定のパスを参照させたくないとき」にダブりがあると、期待された結果が得られないことがあるのですが、こうすることでわかりやすくしています。

パスの設定が終わったら新規でコマンドプロンプトを開き、

$php -r "phpinfo();" | grep -i thread
Thread Safety => disabled

として動作しているのを確認します。
インストールされたものを眺めてみると、 c:\Apps\PHP\ext 以下にモジュールが一通り入っていますので、iconv や mbstring、gd、exif などのインストールは必要なさそうです。また MySQL ドライバとしては、mysqli と pdo_mysql が両方含まれています。WordPress からはどちらでも使えるようなので、心に留めておきます。

FastCGIの設定

Nginx と PHP をインストールしたので、WordPress をインストールする前に FastCGI で PHP を動作させる確認をします。
参考にするのは、Nginx のサイトから PHP-FastCGI on WindowsPHP FastCGI Exampleです。それに PHP のサイトにも FastCGI Process Manager (FPM) というページがありますが、これは FPM を使用する場合なので今回は無関係です。そもそも Windows 版には php-fpm.exe は付属していません。

上記のページには、コンソールを隠した状態で起動したい場合についても書いてあります。lighttph のサイトからRunHiddenConsole.exeというヘルパーアプリをダウンロードして使えばいいとありますが、ここでは使いません。常時サービスするわけでもありませんので。

さて、FastCGI を動かすには、すでにインストールされている php-cgi.exe を引数付きで起動すればよいようです。

php-cgi.exe -b 127.0.0.1:9123

ローカルホストのポート9123にバインドする、というオプションで起動します。ポート番号は任意ですが、WikipediaのTCPやUDPにおけるポート番号の一覧などを参考に空きポートを利用するのがよいでしょう。特にこだわりはないので上記のポート番号を利用することにします。ただし、外部に開放する場合にはファイアウォールなどでポートアクセスを弾く設定も必要になりますので、下手にこだわるよりはデフォルトのまま利用したほうが、あとから見て「これなんのポートだっけ?」ということになりにくいです。

さて、コマンドプロンプトを開いて上記のコマンドを実行すると、コンソールには何も表示されずにプログラムは実行状態になります。これはリクエストを待っている状態です。

次に Nginx の設定を行います。

まずはドキュメントルートを作成します。ここでは c:\srv\www としておきます。これは Linux Foundation の Filesystem Hierarchy Standard (FHS) に定義されているディレクトリ構造によります。詳細は 3.17. /srv : Data for services provided by this system を参照。ただし Linux Distribution によっては /var/www などとしているものもあります。このへんについてはコンセンサスが取れていないようですが、ここでは直感的に「サーブされるデータ」ということで /srv にしておきます。

ドキュメントルートが決まったら、これをnginx.conf に反映します。

上記ページには、
root c:/www;

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

となっていますが、c:\Apps\Nginx\conf\nginx.conf を以下のように修正します。

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9123
#
location ~ \.php$ {
    root           c:/srv/www;
    fastcgi_pass   127.0.0.1:9123;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $fastcgi_script_name;
    include        fastcgi_params;
    include        fastcgi.conf;
}

念のため、何かあれば参照できるようにもともとの nginx.conf は nginx.conf.orig とでも名前を変えて保存してから、編集します。実際には nginx.con の63行目から同様の記述があるので、そこのコメントを外していじればOKです。

ここでひとつ注意しなくてはならないのは、コンソール(コマンドプロンプト)から nginx.exe を起動すると、それを終了することが困難な点です。これはバッチファイルでも同じ。
すでに nginx を起動しているコンソールがあるとして、別のコンソールから nginx -s stop などとしても

nginx: [alert] could not open error log file: CreateFile() "logs/error.log" failed (3: The system cannot find the path specified)
2018/10/29 13:04:11 [emerg] 1588#5708: CreateFile() "C:\Apps\Nginx/conf/nginx.conf" failed (3: The system cannot find the path specified)

などとでてきて停止も終了もできません。もちろん nginx.conf を更新してから reload させようとしても同じようです。そこでコンソールを閉じても、実はバックグラウンドジョブとして nginx が生き残ってしまうので、nginx.conf を修正して再起動したつもりでもちゃんと反映されない、ということになります。

コンソールから起動した nginx.exe を終了させるには、どうやらタスクマネージャーから nginx.exe を探して一つづつ「タスクの終了」をするか、別のコンソールから taskkill /f /im nginx.exe するしかないようです。

一方、エクスプローラから nginx.exe を直接起動したり、ショートカットを作ってそこから起動した場合にはシグナルを受け取って正常に終了するようです。

php-cgi と nginx を起動したら、PHP のテストファイルを用意します。以下の1行のみのファイルを index.php として c:\srv\www に保存します。

<?php phpinfo(); ?>

そしてブラウザから http://127.0.0.1/index.php にアクセスし、エラーとか応答なしとか "No input file specified." などという文字ではなく、下のようなページが表示されればOKです。

0 件のコメント:

コメントを投稿

Windowsでシンボリックリンクを試してみる。

きっかけは、1つのファイルを別の名前で起動したら違う動きになるようなスクリプトを書く、でした。  busybox なんかでは、同じ実行形式ファイルの名前を、lsにすればlsと同じ、cpとすればcpと同じ動作をするようにしてますが、Pythonスクリプトでそれと同じように argv...