nginx + node.js + pm2でアプリ向けのREST API環境を構築
前回の記事でWeb APIについて勉強し、モバイルアプリからのリクエストはNode.jsで捌くことにした。そのために環境を構築したときの覚書。
環境:CentOS 5.10, Node.js 0.10.21, nginx 1.4.3, pm2 0.6.5
< 2014/05/30 Modified >
CentOS6版も書いたのでそちらも参考に。
1.Node.jsをインストール
< 2013/12/09 Modified >
本番環境の場合は実行ユーザーで作成した方がいいので、この記事の最後の方を参照。
前の記事を参考にnvmでインストールする。
# nvm install v0.10.21
# nvm alias default 0.10.21
2.「Hello World」を作成
プロジェクトディレクトリに移動
# cd /home/project/
ExpressというNode.js向けのフレームワークをベースにする。
restifyというREST Webサービス用に特化したモジュールもあるけど、開発のスピードと下記ベンチマークを参考にExpressを選択。
expressjsの公式ドキュメント通りに「Hello World」を作る。
# vi package.json
{
"name": "hello-world",
"description": "hello world test app",
"version": "0.0.1",
"private": true,
"dependencies": {
"express": "3.x"
}
}
# npm install
# vi app.js
var express = require('express');
var app = express();app.get('/', function(req, res){
res.send('hello world');
});app.listen(3000);
アプリ起動
# node app
別コンソールからアクセスして確認
# curl -i http://localhost:3000/
3.nginxを設定してブラウザから外部からアクセス
既にnginx + php-fpm + WordPressの環境があるので、リバースプロキシの設定をして外部から参照可能にする。
WordPressのサブディレクトリで動作させたかったので、ファイルが存在しなかったときのパーマリンクの動作を修正。
# vi /etc/nginx/conf.d/hoge.conf
server {
listen 80;
server_name wordpress.hoge.net;### Reverse Proxy for API
location /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:3000;
}### if the file is not found, forwarded to index.php (permalinks)
set $rewrite_flg "false";
if (!-e $request_filename) {
set $rewrite_flg "true";
}
if ($uri ~ "^/api/") {
set $rewrite_flg "false";
}
if ($rewrite_flg = "true") {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
}
ブラウザからアクセスして確認
http://wordpress.hoge.net/api/
「hello world」が表示されるはず。
4.PM2をインストールしてnodeアプリをデーモン化
最後に常時起動させておくようにデーモン化する。
foreverよりpm2の方がクラスタリング(複数プロセスを使った負荷分散)も出来ておすすめらしい。
参考サイト
インストール
$ npm install -g pm2
すると下記エラー
gyp ERR! configure error
gyp ERR! stack Error: Python executable "python" is v2.4.3, which is not supported by gyp.
gyp ERR! stack You can pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.
pythonのバージョンが古いらしい。メッセージにある通り「--python」オプションを利用してみる。
$ yum install python26
$ npm install -g pm2 --python=python26
起動する
$ pm2 start app.js -i max
Warningが出た。
PM2 [ERROR] [Warning], you're using the 0.10.x node version, it's prefered that you switch to fork mode by adding the -x parameter.
node v0.10.xではstopしたときにポートを開放しないので、「fork mode」での動作がオススメらしい。詳しくは下記。
- Fork mode - execute script in different languages - Unitech/pm2
- Known bugs and workarounds - Unitech/pm2
再起動
$ pm2 stop all
$ pm2 start app.js -x
動いているプロセスを表示
$ pm2 list
何が出来るかヘルプをみる
$ pm2 help
ファイルを監視して自動で再起動するのはまだ開発中ということなので、しばらくはnode-devを使って開発していた方がよさそう。
< 2013/12/09 Modified >
本番環境はrootで動かすと恐いのでnodejs実行用のユーザーを作成する。あとで権限の設定をするためにwwwというグループに所属させる。
# groupadd www
# useradd node -G www
# passwd node
所属グループの確認
# groups node
apacheユーザーの所属グループの変更
# usermod -G www apache
apacheユーザーだけが書き込み権限持っていた場所をwwwグループにも権限を与える
# chown apache.www -R /path/to/wordpress/wp-content/uploads
# chmod 775 -R /path/to/wordpress/wp-content/uploads
ユーザー切り替え
# su - node
ここからはnvmのインストールからやり直し。
ちなみにpm2は「-u」オプションで起動ユーザーを指定することができる。$ pm2 -u apache start app.js -x
でもpm2で起動している場合「Permission denied」でファイルの書き込みに失敗する。node-devの場合は成功するのでまた今度調査。
< 2013/12/12 Modified >
nginx + php-fpmで動いている環境もuser=apche, group=wwwで動作するための設定を追記。(今まではuser=apche, group=apache)
php-fpmの設定
# vi /etc/php-fpm.d/www.conf
group = www
nginxの設定
# /etc/nginx/nginx.conf
user apache www;
sessionの書き込みディレクトリの権限(/etc/php-fpm.d/www.confに記述)
# chown apache.www -R /var/lib/php/session/
※YUMでPHPが更新されたときに権限が変更されることがあったので注意。
phpMyAdminが下記エラーで起動しなくてハマった。
2013/12/12 18:44:47 [error] 3653#0: *188 readv() failed (104: Connection reset by peer) while reading upstream
2013/12/12 18:44:47 [error] 3653#0: *187 recv() failed (104: Connection reset by peer) while reading response header from upstream
念のためnginxのキャッシュディレクトリも権限を変更する
# chown apache.www -R /var/cache/nginx/*
< 2013/12/27 Modified >
接続元のIPアドレスを取得したかったので、X-Forwarded-Forの設定を追記。
< Related Posts >