ウェブサイト検索

SystemdとNginxを使用してNode.jsアプリケーションをデプロイする方法


紹介

Dropletにウェブアプリケーションをデプロイする際、開発時と同じような設定、つまりターミナルで「ruby app.rb」や「node server.js」を実行してサーバーを起動することが簡単で魅力的に感じるかもしれません。これはシンプルで簡単であり、ログも視覚的に確認できます。さらに「screen」や「tmux」、あるいは「nohup」を使って、SSHセッションが切断されても動作を続けるようにすることも可能です。しかし、これは危険です。サーバーがクラッシュした場合、再起動する人が周りにいないとどうなるのでしょうか?

この問題を解決するために、永遠とcrontabを使用することができます。このチュートリアルでは、より堅牢ですが、より複雑な解決策を紹介します。systemd(ArchやFedora、将来的にはCentOSで利用可能)を使用することで、Webアプリケーションを徹底的に管理できます:ログ、稼働時間、リソース、cgroupsによるセキュリティ、そして高度なデーモンの起動を統一的にアクセス、制御、および微調整できます。

このチュートリアルでは簡単なNode.jsアプリケーションを使用していますが、他のほとんどのアプリケーション(RubyやPythonなど)にも適用可能です。PHPのウェブアプリケーションの場合は、より専門的なLAMPまたはLEMPスタックを使用することをお勧めします。

FedoraとArchの両方のコマンドが提供されますので、誤設定や混乱を避けるためにどちらがどちらかを注意深く確認してください。特に指示がない限り、コマンドは両方のシステムで同じです。また、ステップバイステップで試みる前に、チュートリアル全体を読むことをお勧めします。そうすることで、内容が何を含むのか、そして自分の状況に適しているかどうかを把握できます。

システムの前提条件

  • systemdを搭載したサーバー。Arch LinuxおよびFedoraのドロップレットは、デフォルトでこのように設定されています。

  • Nginx は、リバースプロキシ HTTP および WebSocket サーバーとして使用されます。

  • Git、nvmをインストールし、gitを使用している場合はアプリケーションをプルします。

  • ルートアクセス。通常のユーザーとしてログインし、すべてのコマンドにsudoを使用することも、su -またはsudo su -を使用してルートプロンプトに切り替えることも可能です。

パッケージをインストールする

アーチ :

pacman -Sy
pacman -S nginx git

フェドーラ :

yum install nginx git

アプリケーションの前提条件

これらはあなたの好みに合わせてカスタマイズできる設定ですが、始める前に決定して設定する必要があります。

ユーザー

アプリケーションは独自のユーザーアカウントで実行されます。名前を選択してください。アプリケーションに関連する名前にすると、記憶しやすく、維持管理が容易になります。ここでは、srv-node-sampleが使用されています。

useradd -mrU srv-node-sample

港

競合を避けるために、高いポートを選んでください。ここでは、「15301」が使用されています。

アプリケーションのセットアップ

アプリケーションを実行するために必要なものをインストールすることから始めます。Node.js(およびRuby、Pythonなど)には2つの選択肢があります:システムのランタイムを使用するか、ユーザー固有のインストール(例えば、nvm、rbenv、RVM、virtualenvなどを使用)を行うかです。

システムノードを使用する

アーチ :

pacman -S nodejs

フェドーラ :

yum install nodejs

ユーザー特定のインストールを使用しています

これはアプリケーションのホームディレクトリ、すなわち /home/srv-node-sample にインストールする必要があります。これはそのユーザーとしてログインすることで最も簡単に行えます。

su srv-node-sample
cd
curl https://raw.github.com/creationix/nvm/master/install.sh | sh
source ~/.nvm/nvm.sh
nvm install 0.10
nvm alias default 0.10

それから、ノードバイナリがインストールされている場所に注意してください:

which node
/home/srv-node-sample/.nvm/v0.10.22/bin/node

アプリケーションをデプロイする

srv-node-sampleにログインしている状態で、コードをデプロイしてください。これは一例に過ぎず、あなたのプロセスは異なる場合があります。

git clone git@server.company.tld:user/repo.git .
npm install
grunt deploy

このチュートリアルでは、次のサンプルアプリケーションが使用されます。

js
var http = require('http');
http.createServer(function(req, res) {
    res.end('<h1>Hello, world.</h1>');
}).listen(15301);

それからルートに戻ります:

exit

Nginxの設定

このチュートリアルでは必要な設定について簡単に説明するだけで、Nginxの設定に関するより詳細なチュートリアルについては「Nginxウェブサーバーの設定方法」またはnginxマニュアルを参照してください。

これをサーバーブロックに配置してください:

location / {
    proxy_pass http://localhost:15301/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

それからそのデーモンを設定します:

systemctl enable nginx
systemctl restart nginx

Systemdの設定

アプリケーションのサービスファイルを/etc/systemd/system/node-sample.serviceに作成してください。

いくつかの変数を埋める必要があります:

  • [nodeバイナリ] これは srv-node-sampleユーザーとしての「which node」の出力です。/usr/bin/node または上記の ~/.nvm/... パスのいずれかです。

  • これはあなたのアプリケーションのメインファイルです。ここに「index.js」があります。

  • srv-node-sampleを置き換えるのを忘れないでください!

[Service]
ExecStart=[node binary] /home/srv-node-sample/[main file]
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=node-sample
User=srv-node-sample
Group=srv-node-sample
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

サービスを開始してください:

systemctl enable node-sample
systemctl start node-sample

使用

ステータス

systemctl status node-sample
node-sample.service
   Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
   Active: active (running) since Fri 2013-11-22 01:12:15 UTC; 35s ago
 Main PID: 7213 (node)
   CGroup: name=systemd:/system/node-sample.service
           └─7213 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...

Nov 22 01:12:15 d02 systemd[1]: Started node-sample.service.

ログ

journalctl -u node-sample
-- Logs begin at Thu 2013-11-21 19:05:17 UTC, end at Fri 2013-11-22 01:12:15 UTC. --
Nov 22 01:12:15 d02 systemd[1]: Starting node-sample.service...
Nov 22 01:12:15 d02 systemd[1]: Started node-sample.service.
Nov 22 01:12:30 d02 node-sample[7213]: Sample message from application

再起動、停止、その他

強制再起動:

systemctl restart node-sample

アプリケーションを停止してください:

systemctl stop node-sample

アプリケーションが停止するか、強制終了された場合、自動的に再起動します:

systemctl status node-sample
node-sample.service
   Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
   Active: active (running) since Fri 2013-11-22 01:12:15 UTC; 35s ago
 Main PID: 7213 (node)
   CGroup: name=systemd:/system/node-sample.service
           └─7213 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...

Nov 22 01:12:15 d02 systemd[1]: Started node-sample.service.

kill 7213

systemctl status node-sample
node-sample.service
   Loaded: loaded (/etc/systemd/system/node-sample.service; enabled)
   Active: active (running) since Fri 2013-11-22 01:54:37 UTC; 6s ago
 Main PID: 7236 (node)
   CGroup: name=systemd:/system/node-sample.service
           └─7236 /home/srv-node-sample/.nvm/v0.10.22/bin/node /home/srv-nod...

Nov 22 01:54:37 d02 systemd[1]: node-sample.service holdoff time over, sch...t.
Nov 22 01:54:37 d02 systemd[1]: Stopping node-sample.service...
Nov 22 01:54:37 d02 systemd[1]: Starting node-sample.service...
Nov 22 01:54:37 d02 systemd[1]: Started node-sample.service.

PIDが変更されており、アプリケーションが確かに終了し再起動されたことを示しています。

ウェブソケット

アプリケーションがWebSocketを使用している場合、Nginxの設定に次の行を追加する必要があります。

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;

そしてNginxを再起動する必要があります:

systemctl reload nginx

関連記事: