Node.js サーバーを 80 番ポートで動かす

  • 34
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

実際はリバースプロキシかましたりして Node.js が動いてるサーバーが外に直接見えることはないんだろうけども。

well known port を使うにはスーパーユーザー権限が必要

ポート 80 はいわゆる well known port なので Linux ではスーパーユーザー権限が必要になる。他の OS は知らん。

なのでそもそも起動に sudo が必要になったりするわけだけどそのままだとサーバープロセスが root で動いてしまって不穏極まりない。

これをなんとかするためにサーバー起動したあとにプロセスの所有権を一般ユーザーに渡す。具体的には以下のようなコード。

hello.js
var http = require('http');
var PORT = 80;
var HOSTNAME = '127.0.0.1';
var USER = 'nodejs';

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(PORT, HOSTNAME, function () {
    console.log('change user');
    process.setuid(USER);
});

console.log('Server running at http://' + HOSTNAME + ':' + PORT + '/');

sudo node hello.js して起動したあとに ps aux | grep node | grep -v grep してみるとユーザーが nodejs になっている。

設定ファイルを使おう

実際はユーザーやポートを環境にあわせて変えたいだろうから設定ファイルとして外出しするのが楽。そんなときは node-config が使える。

https://github.com/lorenwest/node-config

前準備として npm install config してから config/default.json に以下のようなファイルを用意しておく。

config/default.json
{
    "user": "vagrant",
    "port": 80
}

で、 node で以下を起動する。

well-known-port.js
var WELL_KNOWN_PORT = 1024;

var config = require('config');
var port = config.port || 80;
var user = config.user || 'nodejs';

var os = require('os');
var hostname = os.hostname() || '127.0.0.1';

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(port, hostname, function () {
    if (port < WELL_KNOWN_PORT) {
        console.log('Attempting setuid to user "' + user + '"...');
        try {
            process.setuid(user);
            console.log('Succeeded to setuid');
        } catch (err) {
            console.log('Failed to setuid');
            process.exit(1);
        }
    }
});

console.log('Server running at http://' + hostname + ':' + port + '/');

何番を指定されるかわからないので well known port のチェックをしたり、怠惰を貫くためにホスト名を os.hostname を使って引っ張ってきてたりしてるけど、本質は変わってない。