前書き
Node.js is an open source Javascript runtime environment for easily building server-side and networking applications. このプラットフォームはLinux、OS X、FreeBSD、およびWindowsで動作し、そのアプリケーションはJavaScriptで記述されています。 Node.js applications can be run at the command line but we will teach you how to run them as a service, so they will automatically restart on reboot or failure, so you can use them in a production environment.
このチュートリアルでは、2つのCentOS 7サーバーで構成される実稼働対応のNode.js環境のセットアップについて説明します。 1つのサーバーはPM2によって管理されるNode.jsアプリケーションを実行し、もう1つのサーバーはユーザーにアプリケーションサーバーへのNginxリバースプロキシを介してアプリケーションへのアクセスを提供します。
このチュートリアルのUbuntuバージョンはhereにあります。
前提条件
このガイドでは、(同じデータセンター内の)2つのCentOS 7サーバーwith private networkingを使用します。 プライベートネットワークは、新しいサーバーの作成時に(Select additional options
セクションで)構成できます。 以下の名前でそれらを参照します。
-
app:Node.jsランタイム、Node.jsアプリケーション、およびPM2をインストールするサーバー。
-
web:Nginx Webサーバーをインストールするサーバー。これは、アプリケーションのリバースプロキシとして機能します。 ユーザーは、このサーバーのパブリックIPアドレスにアクセスしてNode.jsアプリケーションにアクセスします。
[.note]#Note:現在プライベートネットワークが構成されていない既存のサーバーを使用する場合は、DigitalOcean Documentation - How to Enable Private Networking on Dropletsを参照してください。
#
このガイドを開始する前に、両方のサーバーでsudo
権限を持つ通常の非rootユーザーが構成されている必要があります。これは、サーバーにログインする必要があるユーザーです。 initial server setup guide for CentOS 7をフォローすることで、通常のユーザーアカウントを構成する方法を学ぶことができます。
appサーバーで実行されるコマンド:
an_example_command_on_app
webサーバーで実行されるコマンド:
an_example_command_on_web
このチュートリアルでは単一のサーバーを使用できますが、途中でいくつかの変更を行う必要があります。 localhost IPアドレス、つまり 127.0.0.1
、appサーバーのプライベートIPアドレスが使用されている場合。
以下は、このチュートリアルを実行した後のセットアップの図です。
パブリックIPアドレスではなくドメイン名を介してwebサーバーにアクセスできるようにする場合は、ドメイン名を購入してから、次のチュートリアルに従ってください。
Node.jsランタイムをappサーバーにインストールすることから始めましょう。
[[step-1 -—- installing-node-js]] ==ステップ1—Node.jsのインストール
Node.jsの最新のLTSリリースをappサーバーにインストールします。
sudo
特権を持つ通常の非rootユーザーを使用して、appサーバーにSSHで接続します。
appサーバーで、curl
を使用してNodeSourceRPMリポジトリ構成ファイルをダウンロードしましょう。
curl -L -o nodesource_setup.sh https://rpm.nodesource.com/setup_10.x
CURL
は、HTTPSプロトコルを使用して、セットアップスクリプトをサーバーにダウンロードします。出力には、ダウンロードに関連する情報が含まれます。
Output % Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 11109 100 11109 0 0 70128 0 --:--:-- --:--:-- --:--:-- 70757
次に、スクリプトの内容を調べる必要があります。 次のコマンドは、サーバーコンソールでNodeSourceセットアップスクリプトを開きます。これを(NodeSource Distributions Githubリポジトリからの)NodeSource setup scriptと相互参照して、正しくダウンロードされたスクリプトを確認できます。
vi nodesource_setup.sh
ファイルに問題がなければ、:q
をquit
と入力してvi
を終了し、コマンドラインに戻ります。
次に、セットアップスクリプトを実行してNodeSource RPMリポジトリをインストールします。 これにより、yum
パッケージマネージャー内からNodeSourceのリポジトリにアクセスできるようになります。
sudo -E bash nodesource_setup.sh
スクリプトは、参照用のセットアップに関する情報を出力します。
Output## Installing the NodeSource Node.js 10.x repo...
## Inspecting system...
+ rpm -q --whatprovides redhat-release || rpm -q --whatprovides centos-release || rpm -q --whatprovides cloudlinux-release || rpm -q --whatprovides sl-release
+ uname -m
## Confirming "el7-x86_64" is supported...
+ curl -sLf -o /dev/null 'https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'
## Downloading release setup RPM...
+ mktemp
+ curl -sL -o '/tmp/tmp.2aCcULVx8n' 'https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm'
## Installing release setup RPM...
+ rpm -i --nosignature --force '/tmp/tmp.2aCcULVx8n'
## Cleaning up...
+ rm -f '/tmp/tmp.2aCcULVx8n'
## Checking for existing installations...
+ rpm -qa 'node|npm' | grep -v nodesource
## Run `sudo yum install -y nodejs` to install Node.js 10.x and npm.
## You may also need development tools to build native addons:
sudo yum install gcc-c++ make
## To install the Yarn package manager, run:
curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
sudo yum install yarn
Node.jsをインストールする前に、キャッシュされたすべての情報をyum
から削除することが重要です。 キャッシュをクリアすると、yum
がネットワーク接続を使用して新しいNodeSourceリポジトリからNode.jsを取得するようになります(これにより、古いパッケージによって引き起こされる潜在的な競合が防止されます)。
sudo yum clean all
次に、現在有効になっているyum
リポジトリのすべてのメタデータをダウンロードして使用できるようにします。 これにより、yum
クエリが可能な限り迅速に完了するようになります。
sudo yum makecache fast
npm
からネイティブアドオンをコンパイルしてインストールするには、ビルドツールもインストールする必要があります。
sudo yum install -y gcc-c++ make
これで、Node.jsパッケージの最新リリースをインストールできます。
sudo yum install -y nodejs
次のコマンドでバージョンを確認して、ノードがインストールされていることを確認します。
node -v
出力には、実行中のバージョン番号が表示されます。
Outputv10.16.3
Node.jsランタイムがインストールされ、アプリケーションを実行する準備が整いました。 Node.jsアプリケーションを作成しましょう。
[[step-2 -—- creating-the-node-js-application]] ==ステップ2—Node.jsアプリケーションの作成
次に、HTTPリクエストに"Hello World"
を返すだけのHelloWorldアプリケーションを作成します。 これはNode.jsのセットアップに役立つサンプルアプリケーションです。これを独自のアプリケーションに置き換えることができます。適切なIPアドレスとポートでリッスンするようにアプリケーションを変更してください。
Node.jsアプリケーションでリバースプロキシサーバー(web)からのリクエストを処理する必要があるため、サーバー間通信にはappサーバーのプライベートネットワークインターフェイスを使用します。 appサーバーのプライベートネットワークアドレスを検索します。
サーバーとしてDigitalOceanDropletを使用している場合は、Metadataサービスを介してサーバーのプライベートIPアドレスを検索できます。 appサーバーで、curl
コマンドを使用して今すぐIPアドレスを取得します。
curl -sw "\n" http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address
Node.jsアプリケーションの構成に使用されるため、出力(プライベートIPアドレス)をコピーする必要があります。
次に、Node.jsアプリケーションを作成して開き、編集します。 このチュートリアルでは、vi
を使用して、hello.js
というサンプルアプリケーションを編集します。
vi hello.js
次のコードをファイルに挿入し、強調表示されたAPP_PRIVATE_IP_ADDRESS
アイテムの両方をappサーバーのプライベートIPアドレスに置き換えてください。 必要に応じて、両方の場所で強調表示されたポート8080
を置き換えることもできます(管理者以外のポートを使用してください。 1024
以上):
hello.js
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8080, 'APP_PRIVATE_IP_ADDRESS');
console.log('Server running at http://APP_PRIVATE_IP_ADDRESS:8080/');
ここで、ESC
を押して--INSERT--
モードを終了し、続いて:wq
からwrite
およびquit
を1つのコマンドで押して、保存して終了します。
このNode.jsアプリケーションは、指定されたIPアドレスとポートをリッスンし、200
HTTP成功コードとともに"Hello World"
を返します。 これは、アプリケーションが同じプライベートネットワーク上のサーバー(webサーバーなど)からのみ到達可能であることを意味します。
アプリケーションが機能するかどうかをテストする場合は、appサーバーで次のnode
コマンドを実行します。
node hello.js
[.note]#Note:この方法でNode.jsアプリケーションを実行すると、CTRL+C
。
を押してアプリケーションが強制終了されるまで、追加のコマンドがブロックされます。
webサーバーがappでNode.jsアプリケーションと通信できることを最初にテストすると、Nginxのデバッグを大幅に節約できます。
アプリケーションをテストするには、別のターミナルセッションを開き、webサーバーに接続します。 Webサーバーは同じプライベートネットワーク上にあるため、curl
を使用してappサーバーのプライベートIPアドレスに到達できる必要があります。 必ずappサーバーのプライベートIPアドレスをAPP_PRIVATE_IP_ADDRESS
に置き換え、ポートを変更した場合はポートに置き換えてください。
curl http://APP_PRIVATE_IP_ADDRESS:8080
次の出力が表示される場合、アプリケーションは適切に動作しており、適切なIPアドレスとポートでリッスンしています。
Node Application OutputHello World
適切な出力が表示されない場合は、Node.jsアプリケーションが実行中であり、適切なIPアドレスとポートでリッスンするように構成されていることを確認してください。
appサーバーで、必ずCTRL+C
を押してアプリケーションを強制終了してください。
[[step-3 -—- installing-and-using-pm2]] ==ステップ3—PM2のインストールと使用
次に、Node.jsアプリケーションのプロセスマネージャーであるPM2をインストールします。 PM2は、アプリケーションを管理およびデーモン化(サービスとして実行)する簡単な方法を提供します。
基本的にNode.jsとともにインストールするNodeモジュールのパッケージマネージャーであるNodePackaged Modules(NPM)を使用して、appサーバーにPM2をインストールします。 次のコマンドを使用して、PM2をインストールします。
sudo npm install pm2@latest -g
PM2のいくつかの基本的な使用方法について説明します。
最初に実行したいのは、pm2 start
コマンドを使用して、アプリケーションhello.js
をバックグラウンドで実行することです。
pm2 start hello.js
これにより、アプリケーションがPM2のプロセスリストに追加され、アプリケーションを起動するたびに出力されます。
Output┌──────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────────────┬──────────┐
│ App name │ id │ mode │ pid │ status │ restart │ uptime │ memory │ watching │
├──────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────────────┼──────────┤
│ hello │ 0 │ fork │ 30099 │ online │ 0 │ 0s │ 14.227 MB │ disabled │
└──────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────────────┴──────────┘
ご覧のとおり、PM2は自動的にApp name(ファイル名に基づいて、.js
拡張子なし)とPM2idを割り当てます。 PM2は、プロセスのPID、現在のステータス、メモリ使用量などの他の情報も保持します。
PM2で実行中のアプリケーションは、アプリケーションがクラッシュまたは強制終了すると自動的に再起動されますが、システムの起動時にアプリケーションを起動するために追加の手順を実行する必要があります(ブートまたはリブート)。 幸い、PM2には、これを行う簡単な方法であるstartup
サブコマンドが用意されています。
startup
サブコマンドは、サーバーの起動時にPM2とその管理対象プロセスを起動するための起動スクリプトを生成および構成します。 また、実行しているinitシステム(この場合はsystemd
)を指定する必要があります。
sudo pm2 startup systemd
次のような出力が表示されます。これは、PM2サービスがインストールされたことを示しています。
Output[PM2] Generating system init script in /etc/systemd/system/pm2.service
[PM2] Making script booting at startup...
[PM2] -systemd- Using the command:
su root -c "pm2 dump && pm2 kill" && su root -c "systemctl daemon-reload && systemctl enable pm2 && systemctl start pm2"
[PM2] Dumping processes
[PM2] Stopping PM2...
[PM2] All processes have been stopped and deleted
[PM2] PM2 stopped
[PM2] Done.
PM2が起動時に起動するアプリケーションを認識できるようにするには、現在のプロセスリストを保存する必要があります。 リストを保存するには:
pm2 save
次のような出力が表示されます。これは、PM2プロセスリストが保存されたことを示しています。
Output[PM2] Saving current process list...
[PM2] Successfully saved in /home/deployer/.pm2/dump.pm2
これで、PM2が管理するアプリケーションが起動時に自動的に起動します。
PM2には、アプリケーションに関する情報を管理または検索できる多くのサブコマンドがあります。 引数なしでpm2
を実行すると、チュートリアルのこのセクションよりも詳細にPM2の使用法をカバーする使用例を含むヘルプページが表示されることに注意してください。
このコマンドでアプリケーションを停止します(PM2App name
またはid
を指定します)。
pm2 stop example
次のコマンドを使用してアプリケーションを再起動します(PM2App name
またはid
を指定します)。
pm2 restart example
現在PM2によって管理されているアプリケーションのリストは、list
サブコマンドでも検索できます。
pm2 list
特定のアプリケーションの詳細については、info
サブコマンド(PM2App nameまたはidを指定)を使用して見つけることができます。
pm2 info example
PM2プロセスモニターは、monit
サブコマンドでプルアップできます。 これにより、アプリケーションのステータス、CPU、およびメモリ使用量が表示されます。
pm2 monit
[.note]#Note: PM2のmonit
コマンドを実行すると、CTRL+C
。
を押してアプリケーションが強制終了されるまで、追加のコマンドがブロックされます。
Node.jsアプリケーションが実行され、PM2によって管理されたので、リバースプロキシを設定しましょう。
[[step-4 -—- setting-up-an-nginx-reverse-proxy-server]] ==ステップ4—Nginxリバースプロキシサーバーのセットアップ
アプリケーションが実行され、プライベートIPアドレスをリッスンしているので、ユーザーがアクセスする方法を設定する必要があります。 この目的のために、Nginx Webサーバーをリバースプロキシとして設定します。 このチュートリアルでは、Nginxサーバーをゼロからセットアップします。 すでにNginxサーバーをセットアップしている場合は、location
ブロックを選択したサーバーブロックにコピーするだけです(場所がWebサーバーの既存のコンテンツと競合しないことを確認してください)。
webサーバーで、yumを使用してepel-release
パッケージをインストールしましょう。
sudo yum install epel-release
次に、Nginxをインストールします。
sudo yum install nginx
Nginx構成ファイルを編集用に開きます。
sudo vi /etc/nginx/nginx.conf
まず、デフォルトのサーバーブロック内で、server_name
が定義されている行を見つけます。 これは次のようになります。
nginx.conf excerpt — server_name (before)
server_name _;
サーバー名を更新して、アンダースコア(_
)をserver_name
ディレクティブの独自のドメイン名(またはドメインが設定されていない場合はIPアドレス)に置き換えます。
nginx.conf excerpt — server_name (after)
server_name your-domain;
次に、同じデフォルトのサーバーブロック内で、location /
が定義されている行(通常はserver_nameの下の数行)を見つけます。 これは次のようになります。
nginx.conf excerpt — location / (before)
location / {
}
次のコードブロックに置き換え、APP_PRIVATE_IP_ADDRESS
の代わりにappのサーバープライベートIPアドレスを使用してください。 さらに、アプリケーションが別のポートでリッスンするように設定されている場合は、ポート(8080
)を変更します。
/etc/nginx/nginx.conf excerpt — location / (after)
location / {
proxy_pass http://APP_PRIVATE_IP_ADDRESS: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;
}
これにより、webサーバーがルートで要求に応答するように構成されます。 サーバーがyour-domain
で利用可能であるとすると、Webブラウザーを介してhttp://your-domain/
にアクセスすると、ポート8080
でアプリケーションサーバーのプライベートIPアドレスに要求が送信され、によって受信されて応答されます。 Node.jsアプリケーション。
同じサーバーブロックにlocation
ブロックを追加して、同じwebサーバー上の他のアプリケーションへのアクセスを提供できます。 たとえば、ポート8081
のappサーバーで別のNode.jsアプリケーションも実行している場合は、このロケーションブロックを追加して、http://your-domain/app2
経由でのアクセスを許可できます。
Nginx設定—追加の場所
location /app2 {
proxy_pass http://APP_PRIVATE_IP_ADDRESS: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;
}
アプリケーションのロケーションブロックの編集が完了したら、ESC
を押して--INSERT--
モードを終了し、次に:wq
を押してwrite
を押して、保存して終了します。およびquit
を1つのコマンドで実行できます。
webサーバーで、Nginxを再起動します。
sudo systemctl start nginx
次に、サーバーが再起動するたびにNginxが実行されるようにします:
sudo systemctl enable nginx
enable
コマンドは、次の出力を提供する必要があります
OutputCreated symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
systemctl
からステータスをリクエストすることで、Nginxが実行中であり、有効になっていることを確認することもできます。
sudo systemctl status nginx
statusコマンドは、Nginxサービスの構成情報を出力します。
Output● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2019-10-14 09:37:23 UTC; 3min 29s ago
Main PID: 12818 (nginx)
CGroup: /system.slice/nginx.service
├─12818 nginx: master process /usr/sbin/nginx
└─12819 nginx: worker process
Oct 14 09:37:23 centos-s-1vcpu-1gb-sgp1-01 systemd[1]: Starting The nginx HTTP and reverse proxy server...
Oct 14 09:37:23 centos-s-1vcpu-1gb-sgp1-01 nginx[12814]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Oct 14 09:37:23 centos-s-1vcpu-1gb-sgp1-01 nginx[12814]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Oct 14 09:37:23 centos-s-1vcpu-1gb-sgp1-01 systemd[1]: Failed to read PID from file /run/nginx.pid: Invalid argument
Oct 14 09:37:23 centos-s-1vcpu-1gb-sgp1-01 systemd[1]: Started The nginx HTTP and reverse proxy server.
最後に、Security-Enhanced Linux(SELinux)を介してトラフィックを中継する機能をNginxに提供します。 SELinuxは、Linuxカーネルに必須アクセス制御(MAC)を実装するセキュリティレイヤーを提供します。 各オペレーティングシステムオブジェクト(プロセス、ファイル記述子、ファイルなど)には、オブジェクトが実行できる権限と操作を定義するSELinuxコンテキストのラベルが付けられています。
Nginxはhttpd_t
コンテキストでラベル付けされているため、明示的に許可されていない限り、SELinuxによっていくつかの構成がブロックされます。 これを示すために、次のコマンドを実行して、Nginxサービスにhttpd_t
というラベルが付いていることを確認します。
ps -eZ
このコマンドはプロセスステータス情報を提供し、Nginx固有のプロセス情報を検索してラベルを表示します。 次のように、httpd_t
が表示されます。
Output...
system_u:system_r:httpd_t:s0 10208 ? 00:00:00 nginx
system_u:system_r:httpd_t:s0 10209 ? 00:00:00 nginx
...
次に、httpd_t
SELinuxラベルに関連するデフォルトのブール値のステータスを確認しましょう。 次のコマンドを実行して、この情報を表示できます。
getsebool -a
このチュートリアルでは、httpd
関連のブール値のみに関心があります。
Output...
httpd_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_check_spam --> off
httpd_can_connect_ftp --> off
httpd_can_connect_ldap --> off
httpd_can_connect_mythtv --> off
httpd_can_connect_zabbix --> off
httpd_can_network_connect --> off
httpd_can_network_connect_cobbler --> off
httpd_can_network_connect_db --> off
httpd_can_network_memcache --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> off
httpd_dbus_avahi --> off
httpd_dbus_sssd --> off
httpd_dontaudit_search_dirs --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> off
httpd_execmem --> off
httpd_graceful_shutdown --> on
httpd_manage_ipa --> off
httpd_mod_auth_ntlm_winbind --> off
httpd_mod_auth_pam --> off
httpd_read_user_content --> off
httpd_run_ipa --> off
httpd_run_preupgrade --> off
httpd_run_stickshift --> off
httpd_serve_cobbler_files --> off
httpd_setrlimit --> off
httpd_ssi_exec --> off
httpd_sys_script_anon_write --> off
httpd_tmp_exec --> off
httpd_tty_comm --> off
httpd_unified --> off
httpd_use_cifs --> off
httpd_use_fusefs --> off
httpd_use_gpg --> off
httpd_use_nfs --> off
httpd_use_openstack --> off
httpd_use_sasl --> off
httpd_verify_dns --> off
...
特に注目すべき2つのブール値は、httpd_can_network_connect
とhttpd_can_network_relay
です。 Redhat Documentationは、各httpd
ブール値とそれに関連する関数(各ブール値について詳しく知りたい場合)の詳細を提供しますが、このチュートリアルに関連する2つのブール値の説明は次のとおりです。
...
httpd_can_network_connect: When disabled, this Boolean prevents HTTP scripts and modules from initiating a connection to a network or remote port. Enable this Boolean to allow this access.
httpd_can_network_relay: Enable this Boolean when httpd is being used as a forward or reverse proxy.
...
構成はトラフィックのみを中継しているため、httpd
サーバー(この場合はNginx)がネットワークを使用して、設定したリバースプロキシ構成でトラフィックを中継できることをSELinuxに通知する必要があります。 -P
フラグを使用して、変更が永続的であることを確認します(このフラグを省略すると、サーバーの再起動時にhttpd_can_network_relay
がデフォルトの状態(オフ)に戻ります)。
sudo setsebool -P httpd_can_network_relay on
Node.jsアプリケーションが実行されていて、アプリケーションとNginxの構成が正しいと仮定すると、webサーバーのリバースプロキシを介してアプリケーションにアクセスできるはずです。 webサーバーのURL(パブリックIPアドレスまたはドメイン名)にアクセスして試してみてください。
[.note]#Note:webサーバーを使用して(従来の仮想ホストとして)他のサイトをホストすることも計画している場合は、httpd_can_network_connect
をオンに設定する必要もあります。 。
#
結論
これで、Node.jsアプリケーションがNginxリバースプロキシの背後で実行されました。 このリバースプロキシのセットアップは、ユーザーが共有したい他のアプリケーションまたは静的なWebコンテンツにアクセスできるように十分な柔軟性を備えています。
また、Webサーバーとユーザー間の送信を暗号化する場合は、here is a tutorial that will help you get HTTPS (TLS/SSL) support set upを使用します。