うしこlog
公開: 2015/09/01

Node.jsでラズパイ2をWebサーバにする

今回の内容

 ラズベリーパイ2をWebサーバとして使うためにNode.jsをインストールし、その使い方を説明します。また、Node.jsのフレームワークであるExpressを使ってWebサーバの作成の流れを説明していきます。

前回までの内容は?

 前回までで、ラズパイを使うための設定(OSのインストール,SSH等)をして、エアコンの操作や、Juliusによる音声認識、Apacheでのサーバの構築をラズパイ上で行ってきました。
前回までの内容が気になる方や、ラズベリーパイをもっと活用したい方 は、ぜひ以下の記事をご確認ください。

Node.jsのインストール

 前に掲載したnode.jsでラズパイをWebサーバにするという記事と同じ要領で、ラズパイ2にもnode.jsをインストールしようとしたのですが失敗したので別の方法を紹介します。

 ラズパイ2で、nodebrewを使ってnode.jsをインストールしようとすると"Error: Linux armv7| is not supported."というエラーがでます。

ラズパイ2でのnode.jsインストールエラー
ラズパイ2でのnode.jsインストールエラー

 そのため、今回はnodebrewを使用せずにnode.jsをインストールします。ラズパイ2でnode.jsをインストール方法は以下の2つあります。

ラズパイ2でnode.jsをインストールする2つの方法

  1. node-armページからインストール (おすすめ)
  2. nodejs公式ページからインストール

 1つ目は、node-arm.herokuapp.comさんのページからダウンロード・インストールする方法です。最新バージョンはインストールできませんが、この方法がおすすめです。

 2つ目は、node公式ページからダウンロード・インストールする方法です。最新バージョンもインストールできます。

 これから、上記2つの方法でラズパイ2にnode.jsをインストールする方法について説明していきます。

方法1. node-armページからインストール

 まずnode-arm.herokuapp.comさんのページからダウンロード・インストールする方法を説明します。この方法は、最新のバージョンと、v0.12.0より前のバージョンはインストールできませんが、簡単にラズパイ2上にインストールできるので、おすすめの方法です。ここで紹介するダウンロードとインストール方法は、node-arm.herokuapp.comに記載されている方法です。

node-armさんのページ
node-armさんのページ

 以下のコマンドより、node-arm.herokuapp.comさんのページ上でのnode.js最新バージョンをダウンロードします。

wget http://node-arm.herokuapp.com/node_latest_armhf.deb
node-armからダウンロード
node-armからダウンロード

 または、以下のコマンドでv0.12.0以降のバージョンを指定してダウンロードすることもできます。以下の例はv0.12.1を指定してダウンロードしています。ダウンロード可能なバージョンはnode-arm.herokuapp.comをご覧ください。

wget http://node-arm.herokuapp.com/node_0.12.1_armhf.deb

 ダウンロードしたファイルをラズパイ2上にインストールします。ダウンロードしたファイルを"-i"の後に指定してインストールしましょう。以下の例は、ダウンロードした最新バージョンのnode.jsをインストールする例です。

sudo dpkg -i node_latest_armhf.deb
dpkgでインストール
dpkgでインストール

 インストールできているか確認します。以下のコマンドで、インストールしたnode.jsのバージョンが確認できれば、node.jsのインストールは無事にできています。

node -v
nodeの動作確認
nodeの動作確認

方法2. nodejs公式ページからインストール

 まず公式nodejsのダウンロードページで最新バージョンを確認します。この方法は、どのバージョンでもラズパイ2上にインストールできます。

 ダウンロード可能なバージョンは、公式ページから確認できます。

ラズパイ2-nodejsバージョン一覧
nodejsバージョン一覧

 例えばv0.10.26をクリックすると下図のように、v0.10.26でダウンロード可能なファイル一覧が確認できます。ラズパイ2では基本は「vX.X.X.tar.gz」というソースコードファイルをダウンロードして、自分でコンパイルする必要があります。

 しかし、バージョンによってはラズパイ2用と思われるファイル「vX.X.X-linux-arm-pi.tar.gz」も存在します。このファイルはコンパイル済みなので、自分でコンパイルをする必要はありません。

nodeダウンロードファイル説明
node.jsダウンロードファイルの説明

 つまり、公式ページからダウンロード・インストールする方法は、2つの方法があります。

公式ページからインストールする2つの方法

  1. コンパイル済みファイルでのインストール
  2. ソースコードをコンパイルしてインストール

コンパイル済みファイルでのインストール

 「vX.X.X-linux-arm-pi.tar.gz」が存在するバージョンをインストールする場合の説明をします。このファイルはコンパイル済みなので、ダウンロードしてファイルを/usr/local/に配置するだけでインストール終了です。しかしバージョンによっては、このファイルが存在しませんので、後に紹介するソースコードをコンパイルしてインストールをご覧ください。

 以下のコマンドを実行してファイルをダウンロードします。以下の例では「node-v0.10.26-linux-arm-pi.tar.gz」をダウンロードしています。

wget http://nodejs.org/dist/v0.10.26/node-v0.10.26-linux-arm-pi.tar.gz
pi用のnode.jsをダウンロード
コンパイル済みnode.jsをダウンロード

 以下のコマンドのようにtar.gzファイルを解凍します。

tar zxvf node-v0.10.26-linux-arm-pi.tar.gz
tar.gzファイルの解凍
tar.gzファイルの解凍

 解凍後のファイルに移動して、その中のbinに「node」があることを確認します。

cd ./node-v0.10.26-linux-arm-pi
ls ./bin/
node実行ファイルの確認
node実行ファイルの確認

 node-vX.X.X-linux-arm-pi内のファイルを全て、/usr/local/に移動させます。このやり方ではChangeLogやLISENSE、READMEファイルも一緒にコピーされます。

sudo cp -r * /usr/local/

 ChangeLogやLISENSE、READMEファイルを移動したくない場合は、以下のコマンドにより必要なファイルだけをコピーします(前者よりもこちらの方が正しい)。

sudo cp -r ./bin/ /usr/local/
sudo cp -r ./include/ /usr/local/
sudo cp -r ./lib/ /usr/local/
sudo cp -r ./share/ /usr/local/

 無事にインストールできているか確認します。以下のコマンドでインストールしたnode.jsのバージョンが確認できれば、インストールできています。

node -v
node.js動作確認
node.js動作確認

ソースコードをコンパイルしてインストール

 ソースコードファイル(node-vX.X.X.tar.gz)をコンパイルしてインストールする方法を説明します。結構時間がかかるのでおすすめはしませんが、最新バージョンもインストールできるので一長一短があります。

 以下のコマンドを実行してファイルをダウンロードします。以下の例ではソースコードファイル(node-v0.12.7.tar.gz)をダウンロードしています。

wget http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz
node.jsのソースコードをダウンロード
node.jsのソースコードをダウンロード

 以下のコマンドのようにtar.gzファイルを解凍します。

tar zxvf node-v0.12.7.tar.gz
node.jsのソースコードを解凍
node.jsのソースコードを解凍

 解凍後のファイルに移動して、configureファイルを実行します。

cd ./node-v0.12.7
./configure
configureファイルの実行
移動してconfigureファイルを実行

 "make"を実行し、コンパイルをします。時間は2時間くらいかかります。
※後で調査した所、Jun's Homepageさんのwebページによると並列で処理すれば45分で終わるようです。以下のコマンドは、4並列でコンパイルをする方法です。

make -j 4
nodejsソースコードコンパイル
nodejsソースコードコンパイル

 コンパイルが終わったら、"sudo make install"を実行してインストール終了です。

sudo make install
nodejsのインストール
nodejsのインストール

 無事にインストールできているか確認します。以下のコマンドでインストールしたnode.jsのバージョンが確認できれば、インストールできています。

node -v
node.js動作確認
node.js動作確認

フレームワークのインストール

 フレームワークをインストールする前に、npmコマンドが使えることを確認しておきます。npmは、Node.jsに関するパッケージのインストール等を管理するマネージャです。node.jsをインストールしたときに、一緒にインストールされています。

npm -v

 Node.jsで使うWebフレームワークであるexpressをインストールしていきます。(2014/09/01時点でexpress4がインストールされます)

 以下のコマンドよりexpressをインストールします。-gでクローバル環境でのインストールとなります。

sudo npm install -g express
sudo npm install -g express-generator

expressの使い方

expressで簡単なwebサーバを作成する

 expressを用いて簡単なwebサーバを作ってみます。

 まず、express用のディレクトリを作ります。

mkdir work

 作成したworkディレクトリに移動し、"express -e"コマンドでプロジェクトを作成します。ここではtestというプロジェクト名にしました。コマンド実行後、testディレクトリがwork以下に作成されます。
ついでにejs(テンプレートエンジン)をインストールします。-eでejsを指定できます(ejsを指定しなければjadeになる)。 ejsの詳しい説明と使い方はhira-Blogさんの「EJSに触れてみる」というページが分かり易いと思います。

express -e ejs test
expressを使った例
expressを使った例

 図18のような結果が出力されるので、testに移動後、npm installをします。

cd test && npm install

 そして、以下のコマンドより実行します。

DEBUG=test ./bin/www
または
npm start

 ブラウザを立ち上げて "http://[ラズパイIPアドレス]:3000" にアクセスすると、"Express"と表示されます。

nodejsを使ったwebサーバ
nodejsを使ったwebサーバ

 ところで、expressコマンドで作成されたファイルやディレクトリはどうなっているのでしょう。 expressで作成されたディレクトリやファイルを調べると表1のようになっていました。

ディレクトリおよびファイルの説明
ディレクトリ / ファイル説明
app.jsサーバの設定やビューエンジンの設定を行う
bin/このディレクトリ下には、サーバの作成と起動を行うwwwというファイルが存在する。このファイルをnode.jsで実行することでwebサーバが起動する
node_modules/依存するモジュールが格納されている
package.jsonパッケージ情報が記述されている
public/画像、スクリプト、スタイルシートなどの静的なファイルを格納する
routes/画面遷移の処理を行うスクリプトを格納する
view/ページのテンプレートを格納する

ブラウザにExpressと表示されるまで

wwwファイル

 wwwファイルは/bin/wwwに作成されます。wwwファイルを実行することで、サーバの起動を行っています。
3行目のapp = require('../app')で、app.jsを読み込んでいます。
7行目のapp.listen()によりサーバが起動し始めます。

#!/usr/bin/env node
var debug = require('debug')('test');
var app = require('../app');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
  debug('Express server listening on port ' + server.address().port);
});

app.js

 app.jsは、サーバの設定やビューエンジンの設定を行っています。
8行目routes=require('./routes/index')と、24行目のapp.use('/', routes)により、ルートで表示する内容は "./routes/index.js" が出力した内容となります。

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});
module.exports = app;

index.js

 index.jsは./route/index.jsにあります。このファイルは先ほどのapp.jsと紐付されています。
5~7行で、ルート(http://[ラズパイIP]:3000/)にアクセスしたときの処理が記述されています。

 6行目のres.render('index', { title: 'Express' })により、テンプレートである"./view/index.ejs"を読み込みます。このとき'Express'という文字列をtitleとしてindex.ejsに渡しています。

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

index.ejs

 index.ejsは、図19で"Express"と表示するためのテンプレートであり"./view/index.ejs"にあります。このファイルは先ほどのindex.jsから使われます。

 4行目や8行目に記述されている<%= title %>により、titleの中身を使用することができます。titleの中身は、index.jsのrenderにより渡された"Express"という文字列となります。そのため、ブラウザに"Express"が表示されます。

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>
<< Apache2でラズパイをWebサーバに VPNでラズパイに接続するへ >>