ApacheとNode.jsを連携させる

サービスで使っているポート番号をiptablesで許可してあげればサービス自体は動く。が、それじゃ格好悪いし、セキュリティ上余計なポートは開きたくない。という事でApache経由でNode.jsにアクセスする方法をまとめました。

プロジェクトのディレクトリ構造

$ pwd
/var/www/proj
$ ls -lF
total 32
-rw-r--r-- 1 root root 2011 Aug 20 18:05 app.js
drwxr-xr-x 2 root root 4096 Aug 20 18:04 config/
drwxr-xr-x 2 root root 4096 Aug 20 18:01 helpers/
drwxr-xr-x 8 root root 4096 Aug 20 14:27 node_modules/
-rw-r--r-- 1 root root  266 Aug 20 13:19 package.json
drwxr-xr-x 4 root root 4096 Aug 20 13:19 public/
drwxr-xr-x 2 root root 4096 Aug 20 18:09 routes/
drwxr-xr-x 4 root root 4096 Aug 20 18:11 views/

http.conf

モジュールを有効化します。

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

vhost

/var/www/proj/publicをドキュメントルートに設定します。
ProxyPass/ProxyPassReverseを使い、proj.example.co.jpのリクエストをlocalhost:3000へ流します。

<VirtualHost *:80>
	ServerName proj.example.co.jp
	DocumentRoot "/var/www/proj/public"

	ProxyPass / http://localhost:3000/
	ProxyPassReverse / http://localhost:3000/

	ErrorLog /var/log/httpd/proj-error.log
	LogLevel warn
	CustomLog /var/log/httpd/proj-access.log combined
</VirtualHost>

これでほとんどは問題なかったんですが、Express上でリダイレクトをした際にhttp://localhost:3000/へリダイレクトしてしまいました。これはconfig/config.jsを以下の様に設置し、リダイレクトのコードをドメイン名を使う事で回避する事にしました。

exports.config = {
	domain: 'proj.example.co.jp',
	port: 80
}
var config = res.app.get('config');
var domain_port = '';
if (config.config.port !== 80) {
    domain_port = config.config.domain + ':' + config.config.port;
} else {
    domain_port = config.config.domain;
}
res.redirect('http://' + domain_port + path);