カテゴリー:
Node.js
タグ:
 apache WebSocket node-http-proxy Node.js

このエントリーをはてなブックマークに追加
更新日時:
2012年11月22日(木)
作成日時:
2012年11月22日(木)

前の記事 / 次の記事

前回書いたApacheにリバースプロキシを書く方法だと
Node.jsと連携は出来るけどWebSocketが通らない。

じゃあどうすれば通るんだよ!!
WebSocketがないNode.jsなんて(´・ω・`)

っていうことでざっと調べた感じだとよく使われている方法は次の二つ。

  1. nginxをリバースプロキシとして使う
  2. node-http-proxyをリバースプロキシとして使う

nginxは別途モジュールを導入しないといけないっぽいので
今回は"node-http-proxy"をリバースプロキシとして採用することにした。

主に 【防備録】node.jsでnode-http-proxyを使ってApacheとの共存環境を作ったのでメモ を参考にやってみた。

目指すところは参考ページと同じで、フロントに80番ポートでアクセス出来る node-http-proxy を配置して
サブドメインに応じて80番以外のポートをlistenしてるApacheとNode.jsにそれぞれ振り分けたい。

node-http-proxy (Port 80)
│
├─Apache  (Port 3000)
│
└─Node.js (Port 3001)

こんな感じ。

やること

  1. node-http-proxyのインストール
  2. node-htto-proxyの設定を書く
  3. iptalbesの設定をしていれば今回新たにlistenするポートが通るようにする
  4. Apacheのポートを80番から任意のポート番号に変更
  5. 実行ユーザーのアサインもしくは作成
  6. sudoでnodeできるようにする
  7. Apacheの再起動 → node-http-proxyの起動
  8. foreverに任せる
  9. 参考ページ

環境: CentOS6.3
※ Node.jsのサーバーは最初から3001番ポートで起動しているという前提

1st. node-http-proxy のインストール

インストールする場所はどこでも構わないのだけど、ここでは仮にnode-http-proxy配下に配置することにする。
最終的な構成は以下の通り。

node-http-proxy
│
├node_modules
│└http-proxy
│
└http_proxy.js

node-http-proxy配下に移動して、まずはnode-http-proxyをインストールする。

$ npm install http-proxy

2nd. node-http-proxyの設定を書く

設定というか実行ファイルそのものを作成する訳だけど、ここで振り分けとポート番号を設定する。
ファイル名はなんでもいいんだけど、仮に http_proxy.js を作成する。

最初の参考ページの他Reverse HTTP Proxy (Apache + nodejs)を参考に書いた。

$ vim http_proxy.js

var port = 80;
var httpProxy = require('http-proxy');

var options = {
  hostnameOnly: true,
  router: {
    'inchiki.jp':         '127.0.0.1:3000',
    'node.js.inchiki.jp': '127.0.0.1:3001'
  }
};
var proxyServer = httpProxy.createServer(options);
proxyServer.listen(port, function(){ 
  // 後述
  //process.setuid(任意のUID); 
});

ここでとりあえずテストする場合はアクセス可能な80番以外のポートを指定して

$ node http_proxy.js

※ 80番ポートはroot以外は使用出来ない、これについては後述

3rd. iptalbesの設定をしていれば今回新たにlistenするポートが通るようにする

設定方法によって色々だと思うけど適当にいじって通るようにする。

$ vim /etc/sysconfig/iptables

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3000  -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3001  -j ACCEPT

とか。

4th. Apacheのポート番号を80番から任意のポート番号に変更

node-http-proxyを80番ポートで動かすので、
今まで80番ポートを担当していたApache先生には引っ越ししてもらう。

80で全文検索してそれがポート番号だったら3000にする。

$ vim /etc/httpd/conf/httpd.conf

Listen 3000

ServerName inchiki.jp:3000

NameVirtualHost *:3000

<VirtualHost *:3000>
  ~~
  略
  ~~
</VirtualHost>

5th. 実行ユーザーのアサインもしくは作成

ここまでの設定で、

Apacheを再起動するとApacheは3000番ポートを、
node-http-proxyを起動するとnode-http-proxyは80番ポートをlisten

するようになってるはずだけど、
(1024番未満)80番ポートは特権ポートとして扱われrootじゃないと使用出来ないっていう今となっては謎仕様なので、
頑張ってrootじゃなくても動くようにする。このページを参考に設定した。

rootで動かしても気持ち悪くなければrootで動かせばいいと思う(・∀・)

まず、node-http-serverを動かすのに適当なユーザーを決める。
適当なユーザーがいなかったらuseraddして適当なユーザーをつくる。

$ useradd user-for-node-http-proxy
$ passwd user-for-node-http-proxy

また、そのユーザーがsudoできるようにする。

$ usermod -G wheel user-for-node-http-proxy

で、ユーザーIDを調べて、

$ id -u user-for-node-http-proxy
$ 500

上記の設定コードの”任意のUID”の部分にセットしてコメントを解除する。

$ vim http_proxy.js

var port = 80;
var httpProxy = require('http-proxy');

var options = {
  hostnameOnly: true,
  router: {
    'apache.inchiki.jp':  '127.0.0.1:3000',
    'node.js.inchiki.jp': '127.0.0.1:3001'
  }
};
var proxyServer = httpProxy.createServer(options);
proxyServer.listen(port, function(){ 
  process.setuid(500); 
});

これでroot権限で80番ポートをlistenした直後に実行ユーザーがuser-for-node-http-proxyに切り替わるようなった。
めでたしめでたし。

6th. sudoでnodeできるようにする

と思いきや、このままだとsudoした時にnodeコマンドが使えない。なんで?

パスが通ってないから。

stackoverflowに書いてあったのをそのままもらって来てシンボリックリンクを貼る。

$ sudo ln -s /usr/local/bin/node /usr/bin/node
$ sudo ln -s /usr/local/lib/node /usr/lib/node

# 下の二つは今回不要だけど折角なので一緒につくった
$ sudo ln -s /usr/local/bin/npm /usr/bin/npm
$ sudo ln -s /usr/local/bin/node-waf /usr/bin/node-waf

7th. Apacheの再起動 → proxyサーバ起動

で、やっと起動できる。

当然Apacheを再起動するとサービスが止まるので、実行する時間は要確認で。
このサイトはスーパー過疎ってるのでそんなの考えずにサクサク実行する。

まず、node-http-proxy実行用のユーザーになって、

$ sudo service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [  OK  ]

$ sudo node http_proxy.js

これで当初の予定通りの状態になったはず。

今までapacheで表示出来ていたページがそのまま表示出来て、
Node.jsに割り当てたサブドメインでNode.jsの担当するアプリケーションにアクセス出来れば成功。

8th. foreverに任せる

さて、node-http-proxyを起動したはいいもののこれこのままでどうすんだよw

って思ったので、どうにかするために調べてみるとforeverというツールがあるらしので、
このページを参考にしてforeverを導入する。

# forever は grobal でインストールする必要があるので必ず -g
$ sudo npm install forever -g

foreverを導入することでサービスの起動終了、実行状況をforeverから操作出来て
サービスが落ちた時も自動的に再起動してくれる。

使い方は超簡単で

$ forever start node_httpd_proxy.js

するだけ。今動いてるプロセスを確認するには

$ forever list

この時0とか1とか番号が出てくるので、この番号を指定することでプロセスを停止させることが出来る。

$ forever stop 0

また、起動したファイル名でも停止出来る。

$ forever stop node_httpd_proxy.js

とにかく何もかも停める時は、

$ forever stopall

あとは工夫してサーバー自体が起動した時に一緒に起動するようにしておけばいいのかなと。

おしまい。

参考ページ