前書き
Node.jsは、サーバー側およびネットワークアプリケーションを構築するためのオープンソースのJavaScriptランタイム環境です。 プラットフォームは、Linux、macOS、FreeBSD、およびWindowsで動作します。 Node.jsアプリケーションはコマンドラインで実行できますが、このチュートリアルでは、それらをサービスとして実行することに焦点を当てます。 これは、再起動または障害時に再起動し、運用環境で安全に使用できることを意味します。
このチュートリアルでは、単一のUbuntu 18.04サーバー上に実稼働対応のNode.js環境をセットアップします。 このサーバーは、PM2によって管理されるNode.jsアプリケーションを実行し、Nginxリバースプロキシを介してアプリケーションへの安全なアクセスをユーザーに提供します。 Nginxサーバーは、Let’s Encryptによって提供される無料の証明書を使用してHTTPSを提供します。
前提条件
このガイドでは、次のものがあることを前提としています。
-
initial server setup guide for Ubuntu 18.04で説明されているUbuntu18.04サーバーのセットアップ。 sudo特権とアクティブなファイアウォールを持つ非rootユーザーが必要です。
-
domain name pointed at your server’s public IP。 このチュートリアルでは、全体を通してドメイン名example.comを使用します。
-
How To Install Nginx on Ubuntu 18.04でカバーされているように、Nginxがインストールされています。
-
Let's Encrypt証明書を使用してSSLで構成されたNginx。 How To Secure Nginx with Let’s Encrypt on Ubuntu 18.04は、プロセスを順を追って説明します。
前提条件を完了すると、サーバーがドメインのデフォルトのプレースホルダーページをhttps://example.com/
で提供するようになります。
[[step-1 -—- installing-node-js]] ==ステップ1—Node.jsのインストール
NodeSourceパッケージアーカイブを使用して、Node.jsの最新のLTSリリースをインストールすることから始めましょう。
まず、そのコンテンツにアクセスするためにNodeSource PPAをインストールします。 ホームディレクトリにいることを確認し、curl
を使用してNode.js8.xアーカイブのインストールスクリプトを取得します。
cd ~
curl -sL https://deb.nodesource.com/setup_8.x -o nodesource_setup.sh
このスクリプトの内容は、nano
またはお好みのテキストエディタで調べることができます。
nano nodesource_setup.sh
スクリプトの検査が終了したら、sudo
で実行します。
sudo bash nodesource_setup.sh
PPAが構成に追加され、ローカルパッケージキャッシュが自動的に更新されます。 Nodesourceからセットアップスクリプトを実行した後、Node.jsパッケージをインストールできます。
sudo apt install nodejs
これらの最初の手順の後にインストールしたNode.jsのバージョンを確認するには、次のように入力します。
nodejs -v
Outputv8.11.3
[.note]#Note: NodeSource PPAからインストールする場合、Node.js実行可能ファイルはnode
ではなくnodejs
と呼ばれます。
#
nodejs
パッケージには、nodejs
バイナリとノードモジュールのパッケージマネージャーであるnpm
が含まれているため、npm
を個別にインストールする必要はありません。
npm
は、ホームディレクトリの構成ファイルを使用して更新を追跡します。 npm
を初めて実行したときに作成されます。 次のコマンドを実行して、npm
がインストールされていることを確認し、構成ファイルを作成します。
npm -v
Output5.6.0
一部のnpm
パッケージ(たとえば、ソースからコードをコンパイルする必要があるパッケージ)を機能させるには、build-essential
パッケージをインストールする必要があります。
sudo apt install build-essential
これで、ソースからコードをコンパイルする必要があるnpm
パッケージを操作するために必要なツールができました。
Node.jsランタイムをインストールしたら、Node.jsアプリケーションの作成に進みましょう。
[[step-2 -—- creating-a-node-js-application]] ==ステップ2—Node.jsアプリケーションの作成
HTTPリクエストに「HelloWorld」を返すHello Worldアプリケーションを作成しましょう。 このサンプルアプリケーションは、Node.jsのセットアップに役立ちます。 独自のアプリケーションに置き換えることができます。適切なIPアドレスとポートでリッスンするようにアプリケーションを変更することを確認してください。
まず、hello.js
というサンプルアプリケーションを作成しましょう。
cd ~
nano hello.js
次のコードをファイルに挿入します。
~/hello.js
const http = require('http');
const hostname = 'localhost';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
ファイルを保存し、エディターを終了します。
このNode.jsアプリケーションは、指定されたアドレス(localhost
)とポート(3000
)をリッスンし、「HelloWorld!」を返します。 200
HTTP成功コードを使用します。 localhost
をリッスンしているため、リモートクライアントはアプリケーションに接続できません。
アプリケーションをテストするには、次を入力します。
node hello.js
次の出力が表示されます。
OutputServer running at http://localhost:3000/
[.note]#Note:この方法でNode.jsアプリケーションを実行すると、CTRL+C
。
を押してアプリケーションが強制終了されるまで、追加のコマンドがブロックされます。
アプリケーションをテストするには、サーバーで別のターミナルセッションを開き、curl
を使用してlocalhost
に接続します。
curl http://localhost:3000
次の出力が表示される場合、アプリケーションは適切に動作しており、正しいアドレスとポートでリッスンしています。
OutputHello World!
予想される出力が表示されない場合は、Node.jsアプリケーションが実行され、適切なアドレスとポートでリッスンするように構成されていることを確認してください。
動作していることを確認したら、CTRL+C
を押して、アプリケーションを強制終了します(まだ実行していない場合)。
[[step-3 -—- installing-pm2]] ==ステップ3—PM2のインストール
次に、Node.jsアプリケーションのプロセスマネージャーであるPM2をインストールします。 PM2を使用すると、アプリケーションをデーモン化して、サービスとしてバックグラウンドで実行できます。
npm
を使用して、サーバーに最新バージョンのPM2をインストールします。
sudo npm install pm2@latest -g
-g
オプションは、npm
にモジュールgloballyをインストールするように指示し、システム全体で使用できるようにします。
まず、pm2 start
コマンドを使用して、アプリケーションhello.js
をバックグラウンドで実行します。
pm2 start hello.js
これにより、アプリケーションがPM2のプロセスリストに追加され、アプリケーションを起動するたびに出力されます。
Output[PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/sammy/hello.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬───────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├──────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼───────┼──────────┤
│ hello │ 0 │ fork │ 1338 │ online │ 0 │ 0s │ 0% │ 23.0 MB │ sammy │ disabled │
└──────────┴────┴──────┴──────┴────────┴─────────┴────────┴─────┴───────────┴───────┴──────────┘
Use `pm2 show ` to get more details about an app
ご覧のとおり、PM2は自動的にApp name
(ファイル名に基づいて、.js
拡張子なし)とPM2id
を割り当てます。 PM2は、プロセスのPID
、現在のステータス、メモリ使用量などの他の情報も保持します。
PM2で実行されているアプリケーションは、アプリケーションがクラッシュまたは強制終了された場合に自動的に再起動されますが、startup
サブコマンドを使用して、システムの起動時にアプリケーションを起動するための追加の手順を実行できます。 このサブコマンドは、サーバーの起動時にPM2とその管理対象プロセスを起動するための起動スクリプトを生成および構成します。
pm2 startup systemd
結果の出力の最後の行には、PM2をブート時に開始するように設定するために、スーパーユーザー特権で実行するコマンドが含まれます。
Output[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
sammy
の代わりにユーザー名を使用して、出力からコマンドを実行します。
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
追加の手順として、PM2プロセスリストと対応する環境を保存できます。
pm2 save
これで、起動時にユーザーに対してpm2
を実行するsystemdunitが作成されました。 このpm2
インスタンスは、次にhello.js
を実行します。
systemctl
でサービスを開始します。
sudo systemctl start pm2-sammy
systemdユニットのステータスを確認します。
systemctl status pm2-sammy
systemdの詳細な概要については、Systemd Essentials: Working with Services, Units, and the Journalを参照してください。
取り上げたものに加えて、PM2には、アプリケーションに関する情報を管理または検索できる多くのサブコマンドが用意されています。
このコマンドでアプリケーションを停止します(PM2App name
またはid
を指定します)。
pm2 stop app_name_or_id
アプリケーションを再起動します。
pm2 restart app_name_or_id
現在PM2によって管理されているアプリケーションをリストします。
pm2 list
App name
を使用して、特定のアプリケーションに関する情報を取得します。
pm2 info app_name
PM2プロセスモニターは、monit
サブコマンドでプルアップできます。 これにより、アプリケーションのステータス、CPU、およびメモリ使用量が表示されます。
pm2 monit
引数なしでpm2
を実行すると、使用例を示すヘルプページも表示されることに注意してください。
Node.jsアプリケーションがPM2で実行および管理されたので、リバースプロキシを設定しましょう。
[[step-4 -—- setting-up-nginx-as-a-reverse-proxy-server]] ==ステップ4—Nginxをリバースプロキシサーバーとして設定する
アプリケーションはlocalhost
で実行およびリッスンしていますが、ユーザーがアプリケーションにアクセスする方法を設定する必要があります。 この目的のために、Nginx Webサーバーをリバースプロキシとして設定します。
前提条件のチュートリアルでは、/etc/nginx/sites-available/example.com
ファイルでNginx構成を設定します。 このファイルを編集用に開きます。
sudo nano /etc/nginx/sites-available/example.com
server
ブロック内に、既存のlocation /
ブロックが必要です。 そのブロックの内容を次の構成に置き換えます。 アプリケーションが別のポートでリッスンするように設定されている場合、強調表示された部分を正しいポート番号に更新します。
/etc/nginx/sites-available/example.com
server {
...
location / {
proxy_pass http://localhost:3000;
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
でポート3000
をリッスンします。
同じサーバーブロックにlocation
ブロックを追加して、同じサーバー上の他のアプリケーションへのアクセスを提供できます。 たとえば、ポート3001
で別のNode.jsアプリケーションも実行している場合は、このロケーションブロックを追加して、https://example.com/app2
経由でのアクセスを許可できます。
/etc/nginx/sites-available/example.com — Optional
server {
...
location /app2 {
proxy_pass http://localhost:3001;
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 18.04サーバー上のNginxリバースプロキシの背後でNode.jsアプリケーションを実行できます。 このリバースプロキシのセットアップは、ユーザーが共有したい他のアプリケーションまたは静的なWebコンテンツにアクセスできるように十分な柔軟性を備えています。