node.js v0.12.0 インストール レンタルサーバー さくらスタンダード編

node.js v0.12.0 インストール レンタルサーバー さくらスタンダード編のイメージ node.js

サーバーサイド javascriptの代名詞ともいえるnode.js、せっかくならインターネット側で動作させてみたくなります。

さくらインターネットのスタンダードプランは、
月額515円で、100Gバイトの容量が使えます。

また、なんといってもシェルログインが可能なのが魅力です。

契約時に割り当てられるサーバーの一例として
 OS:FreeBSD 9.x (amd64)、CPU:Intel Xeon E321xx、MEM:18GB
というようなスペックになります。

シェルログインが可能なホスティングサービスとしては、エックスサーバーなどもあります。

シェルでログインが可能といっても、ルート権限が付与されるわけではありません。
あくまで割り当てられたフォルダ内に関する権限にとどまります。

ログインするために・・・ssh環境を整える

Windows7, Windows8/8.1などのPCを利用している場合は、TeraTermやPuttyなどをインストールします。
これでsshでログインするための環境が手に入ります。
FFFTP、WinSCP、Puttyなどをインストールしておくことで、さらに使い勝手がよくなります。

操作する対象は、FreeBSD、UnixOSです。ある程度Unixに関する知識が必要となります。
知識が増してくると、TeraTermだけでは少し役不足というシーンも多々でてきます。

そう感じたら・・・
VirtualBoxなどの仮想環境でFreeBSD/Linuxなどをインストールする、
Cygwin/CoLinuxなどWindowsネイティブ環境で動作するUnix環境をインストールする
などの方法があります。

ここではMac OS 10.10.2を使って説明しています。

ここで利用したコマンド

  • wget

    インターネット上のファイルをダウンロードするコマンド

  • vi

    ファイル編集コマンド

  • ./configure

    環境に合わせたメイクファイルの作成

  • tar

    tar形式のアーカイブファイルの解凍、作成コマンド

ログインする

ターミナルソフトを起動します。以下コマンドでログインできます。
$ ssh [ユーザ名]@[ユーザ名].sakura.ne.jp

[ユーザ名]は契約時に指定したアカウントです。

node.js v0.12.0 をさくらスタンダードにインストール

2015/3/9時点で最新のnode.jsをインストールします。(若干はまりどころがあります)

node.js 0.12.0 https://github.com/joyent/node/wiki

local/srcフォルダにnode.jsのソースファイルをダウンロードします。

$ cd ~/
$ mkdir -p local/src
$ cd local/src

$ wget http://nodejs.org/dist/v0.12.0/node-v0.12.0.tar.gz

https://nodejs.org/download/を確認して最新版のURLを取得してください。

node-v0.12.0の解凍

ダウンロードしたnode-v0.12.0.tar.gzを~/local/src/に展開します。
$ pwd
/home/[ユーザ名]/local/src
$ tar xvzf node-v0.12.0.tar.gz

$ cd node-v0.12.0

configureの実行

node.jsのメイクファイルを作成します。
$ pwd
/home/[ユーザ名]/local/src/node-v0.12.0

$ ./configure –with-intl=small-icu –download=all –prefix=$HOME/local

このままコンパイルすると幾つかエラーが発生します。

コンパイルエラーを回避するために手を加えていきます。

exeinfo.h No such file or directoryを回避する

../deps/v8/src/base/logging.cc:9:23: warning: execinfo.h: No such file or directory
../deps/v8/src/base/logging.cc: In function ‘void v8::base::DumpBacktrace()’:
../deps/v8/src/base/logging.cc:25: error: ‘backtrace’ was not declared in this scope
../deps/v8/src/base/logging.cc:26: error: ‘backtrace_symbols’ was not declared in this scope

libexecinfo.a/libexecinfo.so/execinfo.hが必要です。

ダウンロードしたファイルに手を加える必要があるため、mac OSX側で作業しています

freebsd.orgからpkgをダウンロードします。
(http://portsmon.freebsd.org/portoverview.py?category=devel&portname=libexecinfo)

mac$ mkdir /tmp/a
mac$ cd /tmp/a
mac$ wget http://pkg.freebsd.org/freebsd:11:x86:32/latest/All/libexecinfo-1.1_3.txz

mac$ tar tvzf libexecinfo-1.1_3.txz
-rw-r–r– 0 root wheel 733 1 1 1970 +COMPACT_MANIFEST
-rw-r–r– 0 root wheel 1348 1 1 1970 +MANIFEST
-r–r–r– 0 root wheel 1713 3 7 20:40 /usr/local/include/execinfo.h
-r–r–r– 0 root wheel 68312 3 7 20:40 /usr/local/lib/libexecinfo.a
lrwxr-xr-x 0 root wheel 0 3 7 20:40 /usr/local/lib/libexecinfo.so -> libexecinfo.so.1
-r–r–r– 0 root wheel 61424 3 7 20:40 /usr/local/lib/libexecinfo.so.1
-rw-r–r– 0 root wheel 1133 3 7 20:40 /usr/local/share/doc/libexecinfo/README

/usr/local/と絶対パスで記載されているため、このまま解凍するとアクセス権がない場所へ展開しようとしてしまいます。
paxコマンドを使います。(freebsdにもありますが、バージョンの違いのためか、目的とした動作が上手くいきませんでした)

mac$ pax -rz -v -f ./libexecinfo-1.1_3.txz -s “/\/usr\/local\///g”
(libexecinfo-1.1_3.txzの/usr/local/を除去した上で展開しています。)

展開したlibexecinfoの必要ファイルをまとめて、さくらスタンダード側へ転送します。
mac$ tar cvzf execinfo.tar.gz ./include/execinfo.h ./lib/* ./share/doc/*
mac$ scp execinfo.tar.gz [ユーザ名]@[ユーザ名].sakura.ne.jp:~/local/.

execinfo.tar.gzを展開します

さくらスタンダード側の作業です。
$ cd ~/local
$ tar xvzf execinfo.tar.gz

v8.gypを編集します

$ vi src/node-v0.12.0/deps/v8/tools/gyp/v8.gyp

freebsdで検索します。
変更前

    ['OS=="freebsd"', {
            'link_settings': {
              'libraries': [
                '-L/usr/local/lib -lexecinfo',
            ]},
            'sources': [
              '../../src/base/platform/platform-freebsd.cc',
              '../../src/base/platform/platform-posix.cc'
            ],
          }
        ],

変更後

    ['OS=="freebsd"', {
            'include_dirs+':[
                '/home/ユーザ名/local/include'
            ],
            'link_settings': {
              'libraries': [
                '-L/usr/local/lib -L${HOME}/local/lib -lexecinfo',
            ]},
            'sources': [
              '../../src/base/platform/platform-freebsd.cc',
              '../../src/base/platform/platform-posix.cc'
            ],
          }
        ],

~/.cshrcを編集します

$ vi ~/.cshrc
.cshrcの下部に以下を追記します。
setenv PATH ${PATH}:${HOME}/local/bin
setenv NODE_PATH ${HOME}/local/lib/node_modules
setenv NODE_MODULES ${HOME}/local/bin/node_modules
setenv LD_LIBRARY_PATH ${HOME}/local/lib
setenv LD_RUN_PATH ${HOME}/local/lib

変更を適用します

$ source ~/.cshrc
$ cd ~/local/src/node-v0.12.0
$ ./configure –with-intl=small-icu –download=all –prefix=$HOME/local
(2度目以降はすぐに完了します)

platform-freebsd.ccコンパイルエラーの回避

../deps/v8/src/base/platform/platform-freebsd.cc: In static member function ‘static std::vector > v8::base::OS::GetSharedLibraryAddresses()’:
../deps/v8/src/base/platform/platform-freebsd.cc:159: error: request for member ‘push_back’ in ‘result’, which is of non-class type ‘int’

node-v0.12.0限定だと思われます。次のバージョンでは不要の対策であると信じたい。
参考:https://github.com/joyent/node/issues/9175

$ vi ./deps/v8/src/base/platform/platform-freebsd.cc
青色のように修正します

std::vector OS::GetSharedLibraryAddresses() {
  std::vector address_result;
  static const int MAP_LENGTH = 1024;
  int fd = open("/proc/self/maps", O_RDONLY);
  if (fd < 0) return address_result;
  while (true) {
    char addr_buffer[11];
    addr_buffer[0] = '0';
    addr_buffer[1] = 'x';
    addr_buffer[10] = 0;
    int result = read(fd, addr_buffer + 2, 8);
    if (result < 8) break;
    unsigned start = StringToLong(addr_buffer);
    result = read(fd, addr_buffer + 2, 1);
    if (result < 1) break;
    if (addr_buffer[2] != '-') break;
    result = read(fd, addr_buffer + 2, 8);
    if (result < 8) break;
    unsigned end = StringToLong(addr_buffer);
    char buffer[MAP_LENGTH];
    int bytes_read = -1;
    do {
      bytes_read++;
      if (bytes_read >= MAP_LENGTH - 1)
        break;
      result = read(fd, buffer + bytes_read, 1);
      if (result < 1) break;
    } while (buffer[bytes_read] != '\n');
    buffer[bytes_read] = 0;
    // Ignore mappings that are not executable.
    if (buffer[3] != 'x') continue;
    char* start_of_path = index(buffer, '/');
    // There may be no filename in this line.  Skip to next.
    if (start_of_path == NULL) continue;
    buffer[bytes_read] = 0;
   address_result.push_back(SharedLibraryAddress(start_of_path, start, end));
  }
  close(fd);
  return address_result;
}

platform-posix.cc コンパイルエラー回避

../deps/v8/src/base/platform/platform-posix.cc: In static member function ‘static int v8::base::OS::GetCurrentThreadId()’:
../deps/v8/src/base/platform/platform-posix.cc:331: error: invalid static_cast from type ‘pthread*’ to type ‘int’

こちらもnode-v0.12.0限定だと思われます。次のバージョンでは不要の対策であると信じたい。
参考:https://github.com/joyent/node/issues/9175

$ vi ./deps/v8/src/base/platform/platform-posix.cc
青色のように修正します

int OS::GetCurrentThreadId() {
#if V8_OS_MACOSX
  return static_cast(pthread_mach_thread_np(pthread_self()));
#elif V8_OS_LINUX
  return static_cast(syscall(__NR_gettid));
#elif V8_OS_ANDROID
  return static_cast(gettid());
#else
  /*return static_cast(pthread_self());*/
  return static_cast((int64_t)(void *)pthread_self());
#endif
}

npmコマンド実行時にError: getaddrinfo EAI_BADFLAGSエラーが発生する対応

この対応をしなくても、コンパイルは完了します。
ただ、npmコマンド実行時、Error: getaddrinfo EAI_BADFLAGSというエラーが発生し、先に進めません。
$ npm install -g socket.io
などが失敗します。

参考:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=197539

$ vi ./lib/dns.js
青色の部分を追記しています。

// Easy DNS A/AAAA look up
// lookup(hostname, [options,] callback)
exports.lookup = function lookup(hostname, options, callback) {
  var hints = 0;
  var family = -1;

  // Parse arguments
  if (hostname && typeof hostname !== 'string') {
    throw TypeError('invalid arguments: hostname must be a string or falsey');
  } else if (typeof options === 'function') {
    callback = options;
    family = 0;
  } else if (typeof callback !== 'function') {
    throw TypeError('invalid arguments: callback must be passed');
  } else if (util.isObject(options)) {
    hints = options.hints >>> 0;
    family = options.family >>> 0;

    if (hints !== 0 &&
        hints !== exports.ADDRCONFIG &&
        hints !== exports.V4MAPPED &&
        hints !== (exports.ADDRCONFIG | exports.V4MAPPED)) {
      throw new TypeError('invalid argument: hints must use valid flags');
    }
    // FIXME(indutny): V4MAPPED on FreeBSD results in EAI_BADFLAGS, because
    // the libc does not support it
    if (process.platform === 'freebsd' && family !== 6) {
      hints &= ~exports.V4MAPPED;
    }

  } else {
    family = options >>> 0;
  }
・・・

コンパル&インストール

$ gmake
$ gmake install

とりえあず超簡単なサンプルを動かす

$ cd ~/

$ vi hello.js

console.log('hello?');

$ node hello.js
hello?

最後に・・

sakura.ne.jpのレンタルサーバーご利用上の注意として
daemonとしてサーバーに常駐するプログラムの実行は禁止されています。

コマンドとしての利用を推奨します。デーモン(バックグラウンドプロセス)として稼働させたい方は、VPS(さくらのVPS 16G
等)をお勧めします。

ご利用上の注意 - レンタルサーバーはさくらインターネット
ご利用上の注意について。さくらのレンタルサーバをご利用になる際の、サービスの注意事項などをご説明します。レンタルサーバーをお考えなら「さくらのレンタルサーバ」をご利用ください。

参考:
Qiita さくらのレンタルサーバ(スタンダード)でNode.jsをインストールする
root権限なしでNode.js、MongoDBをインストールする方法

コメント

タイトルとURLをコピーしました