前書き
Node.js is an open source JavaScript runtime environment for easily building server-side and networking applications. プラットフォームは、Linux、OS X、FreeBSD、およびWindowsで動作します。 Node.js applications can be run at the command line, but we’ll focus on running them as a service, so that they will automatically restart on reboot or failure, and can safely be used in a production environment.
このチュートリアルでは、単一のUbuntu 16.04サーバーでの実稼働対応Node.js環境のセットアップについて説明します。 このサーバーは、PM2によって管理されるNode.jsアプリケーションを実行し、ユーザーにNginxリバースプロキシを介したアプリケーションへの安全なアクセスを提供します。 Nginxサーバーは、Let’s Encryptが提供する無料の証明書を使用してHTTPSを提供します。
前提条件
このガイドでは、次のものがあることを前提としています。
-
initial server setup guide for Ubuntu 16.04で説明されているように、
sudo
特権を持つ非rootユーザーで構成されたUbuntu16.04サーバー。 -
How to Set Up a Host Name with DigitalOceanに従って、サーバーのパブリックIPを指すドメイン名。 このチュートリアルでは、全体を通してexample.comを使用します。
-
Nginxがインストールされ、How To Install Nginx on Ubuntu 16.04でカバーされています
-
Let's Encrypt証明書を使用してSSLで構成されたNginx。 How To Secure Nginx with Let’s Encrypt on Ubuntu 16.04は、プロセスを順を追って説明します。
前提条件を完了すると、サーバーがデフォルトのNginxプレースホルダーページをhttps://example.com/で提供するようになります。
サーバーにNode.jsランタイムをインストールすることから始めましょう。
Node.jsをインストールする
NodeSourceパッケージアーカイブを使用して、Node.jsの最新のLTSリリースをインストールします。
まず、NodeSource PPAをインストールして、そのコンテンツにアクセスする必要があります。 ホームディレクトリにいることを確認し、curl
を使用してNode.js6.xアーカイブのインストールスクリプトを取得します。
cd ~
curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh
このスクリプトの内容は、nano
(またはお好みのテキストエディター)で調べることができます。
nano nodesource_setup.sh
そして、sudo
の下でスクリプトを実行します。
sudo bash nodesource_setup.sh
PPAが構成に追加され、ローカルパッケージキャッシュが自動的に更新されます。 nodesourceからセットアップスクリプトを実行した後、上記と同じ方法でNode.jsパッケージをインストールできます。
sudo apt-get install nodejs
nodejs
パッケージにはnodejs
バイナリとnpm
が含まれているため、npm
を個別にインストールする必要はありません。 ただし、一部のnpm
パッケージ(ソースからコードをコンパイルする必要があるパッケージなど)を機能させるには、build-essential
パッケージをインストールする必要があります。
sudo apt-get install build-essential
Node.jsランタイムがインストールされ、アプリケーションを実行する準備ができました! Node.jsアプリケーションを作成しましょう。
[.note]#Note: NodeSource PPAからインストールする場合、Node.js実行可能ファイルはnode
ではなくnodejs
と呼ばれます。
#
Node.jsアプリケーションを作成する
HTTPリクエストに「HelloWorld」を返すだけのHello Worldアプリケーションを作成します。 これは、Node.jsのセットアップに役立つサンプルアプリケーションであり、独自のアプリケーションに置き換えることができます。適切なIPアドレスとポートでリッスンするようにアプリケーションを変更してください。
Hello World Code
まず、Node.jsアプリケーションを作成して開き、編集します。 このチュートリアルでは、nano
を使用して、hello.js
というサンプルアプリケーションを編集します。
cd ~
nano hello.js
次のコードをファイルに挿入します。 必要に応じて、両方の場所で強調表示されたポート8080
を置き換えることができます(管理者以外のポートを使用してください。 1024以上):
hello.js
#!/usr/bin/env nodejs
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8080, 'localhost');
console.log('Server running at http://localhost:8080/');
ここで保存して終了します。
このNode.jsアプリケーションは、指定されたアドレス(localhost
)とポート(8080
)をリッスンし、200
HTTP成功コードで「HelloWorld」を返します。 localhostをリッスンしているため、リモートクライアントはアプリケーションに接続できません。
テストアプリケーション
アプリケーションをテストするには、hello.js
を実行可能としてマークします。
chmod +x ./hello.js
そして次のように実行します:
./hello.js
OutputServer running at http://localhost:8080/
[.note]#Note:この方法でNode.jsアプリケーションを実行すると、Ctrl-C。
を押してアプリケーションが強制終了されるまで、追加のコマンドがブロックされます。
アプリケーションをテストするには、サーバーで別のターミナルセッションを開き、curl
を使用してlocalhostに接続します。
curl http://localhost:8080
次の出力が表示される場合、アプリケーションは適切に動作しており、適切なアドレスとポートでリッスンしています。
OutputHello World
適切な出力が表示されない場合は、Node.jsアプリケーションが実行中であり、適切なアドレスとポートでリッスンするように構成されていることを確認してください。
動作していることを確認したら、Ctrl+Cを押して、アプリケーションを強制終了します(まだ実行していない場合)。
PM2をインストールする
次に、Node.jsアプリケーションのプロセスマネージャーであるPM2をインストールします。 PM2は、アプリケーションを管理およびデーモン化する簡単な方法を提供します(サービスとしてバックグラウンドで実行します)。
Node.jsとともにインストールするNodeモジュールのパッケージマネージャーであるnpm
を使用して、サーバーにPM2をインストールします。 次のコマンドを使用して、PM2をインストールします。
sudo npm install -g pm2
-g
オプションは、npm
にモジュールgloballyをインストールするように指示し、システム全体で使用できるようにします。
PM2でアプリケーションを管理する
PM2はシンプルで使いやすいです。 PM2のいくつかの基本的な使用方法について説明します。
アプリケーションを開始
最初に実行したいのは、pm2 start
コマンドを使用して、アプリケーションhello.js
をバックグラウンドで実行することです。
pm2 start hello.js
これにより、アプリケーションがPM2のプロセスリストに追加され、アプリケーションを起動するたびに出力されます。
Output[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Starting hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ hello │ 0 │ fork │ 3524 │ online │ 0 │ 0s │ 21.566 MB │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────────────┴──────────┘
Use `pm2 show ` to get more details about an app
ご覧のとおり、PM2は自動的にApp name(ファイル名に基づいて、.js
拡張子なし)とPM2idを割り当てます。 PM2は、プロセスのPID、現在のステータス、メモリ使用量などの他の情報も保持します。
PM2で実行中のアプリケーションは、アプリケーションがクラッシュまたは強制終了すると自動的に再起動されますが、システムの起動時にアプリケーションを起動するために追加の手順を実行する必要があります(ブートまたはリブート)。 幸い、PM2には、これを行う簡単な方法であるstartup
サブコマンドが用意されています。
startup
サブコマンドは、サーバーの起動時にPM2とその管理対象プロセスを起動するための起動スクリプトを生成および構成します。
pm2 startup systemd
結果の出力の最後の行には、スーパーユーザー権限で実行する必要があるコマンドが含まれます。
Output[PM2] Init System found: systemd
[PM2] You have to run this command as root. Execute the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
生成されたコマンド(上記の強調表示された出力と同様ですが、sammy
の代わりにユーザー名を使用)を実行して、PM2を起動時に開始するように設定します(独自の出力からコマンドを使用します)。
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
これにより、起動時にユーザーに対してpm2
を実行するsystemdunitが作成されます。 このpm2
インスタンスは、次にhello.js
を実行します。 systemdユニットのステータスはsystemctl
で確認できます。
systemctl status pm2-sammy
systemdの詳細な概要については、Systemd Essentials: Working with Services, Units, and the Journalを参照してください。
その他のPM2の使用法(オプション)
PM2には、アプリケーションに関する情報を管理または検索できる多くのサブコマンドがあります。 引数なしでpm2
を実行すると、チュートリアルのこのセクションよりも詳細にPM2の使用法をカバーする使用例を含むヘルプページが表示されることに注意してください。
このコマンドでアプリケーションを停止します(PM2App name
またはid
を指定します)。
pm2 stop app_name_or_id
次のコマンドを使用してアプリケーションを再起動します(PM2App name
またはid
を指定します)。
pm2 restart app_name_or_id
現在PM2によって管理されているアプリケーションのリストは、list
サブコマンドでも検索できます。
pm2 list
特定のアプリケーションの詳細については、info
サブコマンド(PM2App nameまたはidを指定)を使用して見つけることができます。
pm2 info example
PM2プロセスモニターは、monit
サブコマンドでプルアップできます。 これにより、アプリケーションのステータス、CPU、およびメモリ使用量が表示されます。
pm2 monit
Node.jsアプリケーションが実行され、PM2によって管理されたので、リバースプロキシを設定しましょう。
Nginxをリバースプロキシサーバーとして設定する
アプリケーションが実行され、localhostをリッスンしているので、ユーザーがアプリケーションにアクセスする方法を設定する必要があります。 この目的のために、Nginx Webサーバーをリバースプロキシとして設定します。
前提条件のチュートリアルでは、/etc/nginx/sites-available/default
ファイルでNginx構成を設定します。 ファイルを編集用に開きます。
sudo nano /etc/nginx/sites-available/default
server
ブロック内には、既存のlocation /
ブロックが必要です。 そのブロックの内容を次の構成に置き換えます。 アプリケーションが別のポートでリッスンするように設定されている場合、強調表示された部分を正しいポート番号に更新します。
/etc/nginx/sites-available/default
. . .
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
これにより、サーバーがルートで要求に応答するように構成されます。 サーバーがexample.com
で利用可能であるとすると、Webブラウザーを介してhttps://example.com/
にアクセスすると、hello.js
に要求が送信され、localhostでポート8080
をリッスンします。
同じサーバーブロックにlocation
ブロックを追加して、同じサーバー上の他のアプリケーションへのアクセスを提供できます。 たとえば、ポート8081
で別のNode.jsアプリケーションも実行している場合は、このロケーションブロックを追加して、http://example.com/app2
経由でのアクセスを許可できます。
/etc/nginx/sites-available/default — Optional
location /app2 {
proxy_pass http://localhost:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
アプリケーションのロケーションブロックの追加が完了したら、保存して終了します。
次のように入力して、構文エラーが発生していないことを確認します。
sudo nginx -t
次に、Nginxを再起動します。
sudo systemctl restart nginx
Node.jsアプリケーションが実行中で、アプリケーションとNginxの構成が正しいと仮定すると、Nginxリバースプロキシ経由でアプリケーションにアクセスできるようになります。 サーバーのURL(パブリックIPアドレスまたはドメイン名)にアクセスして試してください。
結論
おめでとうございます。 これで、Ubuntu 16.04サーバー上のNginxリバースプロキシの背後でNode.jsアプリケーションが実行されました。 このリバースプロキシのセットアップは、ユーザーが共有したい他のアプリケーションまたは静的なWebコンテンツにアクセスできるように十分な柔軟性を備えています。 Node.jsの開発を頑張ってください!