Rocky Linux 9でのNode.jsアプリケーションの本番環境設定方法
はじめに
Node.jsは、サーバーサイドおよびネットワーキングアプリケーションを構築するためのオープンソースのJavaScriptランタイム環境です。このプラットフォームはLinux、macOS、FreeBSD、およびWindowsで動作します。Node.jsアプリケーションはコマンドラインで実行することも可能ですが、このチュートリアルではサービスとして実行することに焦点を当てます。つまり、再起動や障害時に自動的に再開され、本番環境での使用に安全です。
このチュートリアルでは、シングルのRocky Linux 9サーバー上にプロダクションレディなNode.js環境をセットアップします。このサーバーはPM2によって管理されたNode.jsアプリケーションを実行し、Nginxリバースプロキシを介してアプリケーションへの安全なアクセスをユーザーに提供します。NginxサーバーはLet’s Encryptが提供する無料の証明書を使用してHTTPSを提供します。
前提条件
このガイドでは、以下を持っていることを前提としています。
- A Rocky Linux 9 server setup, as described in the initial server setup guide for Rocky Linux 9. You should have a non-root user with sudo privileges and an active firewall.
- A domain name pointed at your server’s public IP. This tutorial will use the domain name example.com throughout.
- Nginx installed, as covered in How To Install Nginx on Rocky Linux 9.
- Nginx configured with SSL using Let’s Encrypt certificates. How To Secure Nginx with Let’s Encrypt on Rocky Linux 9 will walk you through the process.
- Node.js installed on your server. How To Install Node.js on Rocky Linux 9
前提条件を満たすと、ドメインのデフォルトのプレースホルダーページをhttps://example.com/で提供するサーバーが用意されます。
ステップ1 – Node.jsアプリケーションの作成
「Hello World」を返すHTTPリクエストに対応するアプリケーションを作成しましょう。このサンプルアプリケーションはNode.jsの使用方法を学ぶのに役立ちます。ご自身のアプリケーションに置き換えることもできますが、適切なIPアドレスとポートでアプリケーションがリスンするように修正してください。
Rocky Linux 9に標準で付属しているテキストエディタはviです。viは非常に強力なテキストエディタですが、使用経験がないユーザーにとっては少し使いにくいかもしれません。Rocky Linux 9サーバーで構成ファイルの編集を容易にするために、nanoなどのより使いやすいエディタをインストールすることを検討するかもしれません。
- sudo dnf install nano
今、nanoまたはお気に入りのテキストエディタを使用して、hello.jsというサンプルアプリケーションを作成してください。
- nano 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}/`);
});
ファイルを保存してエディタを終了してください。もし、nanoを使用している場合、Ctrl+Xを押し、指示されたらY、そしてEnterを押してください。
このNode.jsアプリケーションは指定されたアドレス(localhost)とポート(3000)でリッスンし、200のHTTP成功コードと共に「Hello World!」を返します。 localhostでリッスンしているため、リモートクライアントはアプリケーションに接続することができません。
あなたのアプリケーションをテストするために、入力してください。
- node hello.js
以下の出力を受け取ります:
Server running at http://localhost:3000/
Note
アプリケーションをテストするために、サーバー上で別のターミナルセッションを開き、curlを使用してlocalhostに接続してください。
- curl http://localhost:3000
以下の出力が得られた場合、アプリケーションは正常に機能し、正しいアドレスとポートでリスニングしています。
Hello World!
出力が期待通りでない場合は、Node.jsアプリケーションが正しく実行され、適切なアドレスとポートでリッスンされるように設定されていることを確認してください。
正常に動作していることを確認したら、まだ終了していない場合はCTRL+Cを押してアプリケーションを終了してください。
ステップ2 – PM2のインストール
では、次にPM2をインストールしましょう。PM2はNode.jsアプリケーションのためのプロセスマネージャです。PM2を使用すると、アプリケーションをデーモン化してバックグラウンドでサービスとして実行することができます。
サーバーに最新バージョンのPM2をインストールするためにnpmを使用してください。
- sudo npm install pm2@latest -g
「-g」オプションは、npmに対してモジュールをグローバルにインストールするよう指示します。これにより、システム全体で利用できるようになります。
まず、バックグラウンドでアプリケーションである hello.js を実行するために、pm2 start コマンドを使用しましょう。
- pm2 start hello.js
これにより、アプリケーションは毎回起動するたびにPM2のプロセスリストに追加されます。
… [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. ┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐ │ id │ name │ mode │ ↺ │ status │ cpu │ memory │ ├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤ │ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │ └────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
上記に示されたように、PM2は自動的にアプリ名を割り当てます(ファイル名を基にして、.jsの拡張子を除く形で)また、PM2はプロセスのPID、現在の状態、メモリ使用量などの他の情報も保持しています。
PM2で実行されているアプリケーションは、アプリケーションがクラッシュしたり終了した場合でも自動的に再起動されますが、スタートアップサブコマンドを使用してアプリケーションをシステム起動時に起動するために追加の手順を取ることができます。このサブコマンドは、PM2とその管理プロセスをサーバーブート時に起動するための起動スクリプトを生成および設定します。
- pm2 startup systemd
… [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy –hp /home/sammy
提供されたコマンドをコピーして実行してください(これにより、Node.jsツールをsudoで実行することによる権限の問題を回避できます)。
- sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy –hp /home/sammy
… [ ‘systemctl enable pm2-sammy‘ ] [PM2] Writing init configuration in /etc/systemd/system/pm2-sammy.service [PM2] Making script booting at startup… [PM2] [-] Executing: systemctl enable pm2-sammy… Created symlink /etc/systemd/system/multi-user.target.wants/pm2-sammy.service → /etc/systemd/system/pm2-sammy.service. [PM2] [v] Command successfully executed. +—————————————+ [PM2] Freeze a process list on reboot via: $ pm2 save [PM2] Remove init script via: $ pm2 unstartup systemd
今、先ほど生成されたシステムサービスをRocky LinuxのSELinuxセキュリティシステムと互換性があるように編集する必要があります。nanoまたはお気に入りのテキストエディタを使用して、/etc/systemd/system/pm2-sammy.serviceを開いてください。
- sudo nano /etc/systemd/system/pm2-sammy.service
設定ファイルの[Service]ブロック内で、PIDFile設定の内容を以下のように/run/pm2.pidに置き換え、他のハイライトされたEnvironment行を追加してください。
「/etc/systemd/system/pm2-sammy.service」
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target
[Service]
Type=forking
User=sammy
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/home/sammy/.local/bin:/home/sammy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/home/sammy/.pm2
PIDFile=/run/pm2.pid
Restart=on-failure
Environment=PM2_PID_FILE_PATH=/run/pm2.pid
ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill
[Install]
ファイルを保存して閉じてください。これで、起動時にユーザーのためにpm2を実行するsystemdユニットが作成されました。そしてそのpm2インスタンスは、hello.jsを実行します。
systemctlでサービスを開始してください。
- sudo systemctl start pm2-sammy
systemdユニットの状態を確認してください。
- systemctl status pm2-sammy
systemdの詳細な概要については、『Systemd Essentials:サービス、ユニット、およびジャーナルの操作』を参照してください。
私たちがカバーしたものに加えて、PM2には多くのサブコマンドがあります。これらのサブコマンドは、アプリケーションの管理や情報の検索を行うことができます。
このコマンドでアプリケーションを停止してください(PM2のアプリ名またはIDを指定してください)。
- pm2 stop app_name_or_id
アプリケーションを再起動する。
- pm2 restart app_name_or_id
現在、PM2によって管理されているアプリケーションをリストアップしてください。
- pm2 list
特定のアプリ名を使用して、そのアプリに関する情報を取得してください。
- pm2 info app_name
PM2プロセスモニターは`monit`サブコマンドで表示することができます。これにはアプリケーションの状態、CPU使用率、およびメモリ使用量が表示されます。
- pm2 monit
引数なしでpm2を実行すると、使用例を含むヘルプページも表示されることに注意してください。
Node.jsアプリケーションが実行されていて、PM2で管理されているので、逆プロキシを設定しましょう。
ステップ3 – Nginxをリバースプロキシサーバーとして設定する。
あなたのアプリケーションはlocalhost上で実行およびリッスンしていますが、ユーザーがアクセスできるようにするには方法を設定する必要があります。この目的のために、Nginxウェブサーバーをリバースプロキシとして設定します。
前提チュートリアルでは、/etc/nginx/conf.d/your_domain.conf ファイルに Nginx の設定をセットアップします。このファイルを編集するために開いてください。
- sudo nano /etc/nginx/conf.d/your_domain.conf
サーバーブロック内には、既存のlocation /ブロックが必要です。このブロックの内容を以下の設定で置き換えてください。アプリケーションが別のポートでリッスンするように設定されている場合は、強調された部分を正しいポート番号に更新してください。
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;
}
...
}
この設定により、サーバーはルートのリクエストに応答するように構成されます。私たちのサーバーがyour_domainで利用可能であると仮定すると、ウェブブラウザ経由でhttps://your_domain/にアクセスすると、ポート3000でlocalhost上でリクエストを受け付けているhello.jsに送信されます。
同じサーバーブロックに追加のロケーションブロックを追加することで、同じサーバー上の他のアプリケーションへのアクセスを提供することができます。例えば、ポート3001で別のNode.jsアプリケーションも実行している場合、https://your_domain/app2 経由でそれにアクセスできるようにこのロケーションブロックを追加できます。
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を再起動してください。 (Nginxをさいきどうしてください。)
- sudo systemctl restart nginx
あなたのNode.jsアプリケーションが実行中であり、アプリケーションとNginxの設定が正しいと仮定すると、Nginxのリバースプロキシを介してアプリケーションにアクセスできるはずです。サーバーのURL(公開されているIPアドレスまたはドメイン名)にアクセスして試してみてください。
結論
おめでとうございます!Rocky Linux 9 サーバー上で、Nginxリバースプロキシを介してNode.jsアプリケーションを実行することができました。このリバースプロキシの設定は、他のアプリケーションや共有したい静的ウェブコンテンツへのユーザーのアクセスを柔軟に提供することができます。
次に、Dockerを使用してNode.jsアプリケーションを構築する方法について調べてみると良いでしょう。