序章

Node.jsは、サーバー側およびネットワーキングアプリケーションを簡単に構築するためのオープンソースのJavascriptランタイム環境です。 プラットフォームはLinux、OS X、FreeBSD、およびWindowsで動作し、そのアプリケーションはJavaScriptで記述されています。 Node.jsアプリケーションはコマンドラインで実行できますが、サービスとして実行する方法を説明します。これにより、再起動または失敗時に自動的に再起動し、実稼働環境で使用できるようになります。

このチュートリアルでは、2台のCentOS7サーバーで構成される本番環境に対応したNode.js環境のセットアップについて説明します。 一方のサーバーはPM2によって管理されるNode.jsアプリケーションを実行し、もう一方のサーバーはユーザーにアプリケーションサーバーへのNginxリバースプロキシを介したアプリケーションへのアクセスを提供します。

このチュートリアルのUbuntuバージョンはここにあります。

前提条件

このガイドでは、(同じデータセンター内の)プライベートネットワークを備えた2台のCentOS7サーバーを使用します。 プライベートネットワークは、新しいサーバーが作成されているときに構成できます( Select additional options セクション)。 それらを次の名前で参照します。

  • app :Node.jsランタイム、Node.jsアプリケーション、およびPM2をインストールするサーバー。
  • web :アプリケーションのリバースプロキシとして機能するNginxWebサーバーをインストールするサーバー。 ユーザーは、このサーバーのパブリックIPアドレスにアクセスして、Node.jsアプリケーションにアクセスします。

注:現在プライベートネットワークが構成されていない既存のサーバーを使用する場合は、DigitalOceanのドキュメント-ドロップレットでプライベートネットワークを有効にする方法を参照してください。

このガイドを開始する前に、root以外の通常のユーザーが sudo 両方のサーバーで構成された特権-これは、サーバーにログインする必要があるユーザーです。 CentOS 7 初期サーバーセットアップガイドに従って、通常のユーザーアカウントを構成する方法を学ぶことができます。

app サーバーで実行されるコマンド:

  1. an_example_command_on_app

web サーバーで実行されるコマンド:

  1. an_example_command_on_web

このチュートリアルでは単一のサーバーを使用することもできますが、途中でいくつかの変更を加える必要があります。 ローカルホストのIPアドレスを使用するだけです。 127.0.0.1appサーバーのプライベートIPアドレスが使用されている場合。

このチュートリアルに従った後のセットアップの図は次のとおりです。

パブリックIPアドレスではなくドメイン名を介してwebサーバーにアクセスできるようにする場合は、ドメイン名を購入してから、次のチュートリアルに従ってください。

Node.jsランタイムをappサーバーにインストールすることから始めましょう。

ステップ1—Node.jsをインストールする

Node.jsの最新のLTSリリースをappサーバーにインストールします。

通常のroot以外のユーザーを使用して、appサーバーにSSHで接続します。 sudo 特権。

app サーバーで、 curl NodeSource RPMリポジトリ構成ファイルをダウンロードするには:

  1. 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セットアップスクリプト(NodeSource Distributions Githubリポジトリから)と相互参照して、正しくダウンロードされたスクリプトを確認できます。

  1. vi nodesource_setup.sh

ファイルに満足したら、終了します vi 入力して :qquit コマンドラインに戻ります。

次に、セットアップスクリプトを実行して、NodeSourceRPMリポジトリをインストールします。 これにより、NodeSourceのリポジトリにアクセスできるようになります。 yum パッケージマネージャー:

  1. 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を取得します(これにより、古いパッケージによって引き起こされる潜在的な競合が防止されます)。

  1. sudo yum clean all

次に、現在有効になっているすべてのメタデータをダウンロードして使用できるようにします yum レポ。 これにより、 yum クエリは可能な限り迅速に完了します。

  1. sudo yum makecache fast

からネイティブアドオンをコンパイルしてインストールするには npm また、ビルドツールをインストールする必要があります。

  1. sudo yum install -y gcc-c++ make

これで、Node.jsパッケージの最新リリースをインストールできます。

  1. sudo yum install -y nodejs

次のコマンドでバージョンを確認して、ノードがインストールされていることを確認します。

  1. node -v

出力には、実行しているバージョン番号が表示されます。

Output
v10.16.3

これでNode.jsランタイムがインストールされ、アプリケーションを実行する準備が整いました。 Node.jsアプリケーションを書いてみましょう。

ステップ2—Node.jsアプリケーションを作成する

次に、単純に戻るHelloWorldアプリケーションを作成します。 "Hello World" すべてのHTTPリクエストに。 これは、Node.jsのセットアップに役立つサンプルアプリケーションであり、独自のアプリケーションに置き換えることができます。適切なIPアドレスとポートでリッスンするようにアプリケーションを変更してください。

Node.jsアプリケーションでリバースプロキシサーバー( web )からのリクエストを処理する必要があるため、サーバー間通信にはappサーバーのプライベートネットワークインターフェイスを使用します。 appサーバーのプライベートネットワークアドレスを検索します。

サーバーとしてDigitalOceanDropletを使用している場合は、メタデータサービスを介してサーバーのプライベートIPアドレスを検索できます。 app サーバーでは、 curl 今すぐIPアドレスを取得するコマンド:

  1. curl -sw "\n" http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address

Node.jsアプリケーションの構成に使用されるため、出力(プライベートIPアドレス)をコピーする必要があります。

次に、編集用にNode.jsアプリケーションを作成して開きます。 このチュートリアルでは、 vi と呼ばれるサンプルアプリケーションを編集するには hello.js:

  1. vi hello.js

次のコードをファイルに挿入し、強調表示された両方のappサーバーのプライベートIPアドレスを必ず置き換えてください APP_PRIVATE_IP_ADDRESS アイテム。 必要に応じて、強調表示されたポートを置き換えることもできます。 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-- モード、続いて :wqwritequit 単一のコマンドで。

このNode.jsアプリケーションは、指定されたIPアドレスとポートをリッスンし、 "Hello World" とともに 200 HTTP成功コード。 つまり、アプリケーションには、webサーバーなどの同じプライベートネットワーク上のサーバーからのみアクセスできます。

アプリケーションが機能するかどうかをテストする場合は、これを実行します node app サーバーでのコマンド:

  1. node hello.js

注:この方法でNode.jsアプリケーションを実行すると、を押してアプリケーションを強制終了するまで、追加のコマンドがブロックされます。 CTRL+C.

webサーバーがapp上のNode.jsアプリケーションと通信できることを最初にテストすると、Nginxのデバッグを大幅に節約できます。

アプリケーションをテストするには、別のターミナルセッションを開き、webサーバーに接続します。 Webサーバーは同じプライベートネットワーク上にあるため、appサーバーのプライベートIPアドレスに到達できる必要があります。 curl. appサーバーのプライベートIPアドレスを必ず置き換えてください APP_PRIVATE_IP_ADDRESS、および変更した場合のポート:

  1. curl http://APP_PRIVATE_IP_ADDRESS:8080

次の出力が表示された場合、アプリケーションは正常に動作しており、適切なIPアドレスとポートでリッスンしています。

Node Application Output
Hello World

適切な出力が表示されない場合は、Node.jsアプリケーションが実行されており、適切なIPアドレスとポートでリッスンするように構成されていることを確認してください。

app サーバーで、を押してアプリケーションを強制終了してください CTRL+C.

ステップ3—PM2のインストールと使用

次に、Node.jsアプリケーションのプロセスマネージャーであるPM2をインストールします。 PM2は、アプリケーションを管理およびデーモン化する(サービスとして実行する)ための簡単な方法を提供します。

基本的にNode.jsとともにインストールするNodeモジュールのパッケージマネージャーであるNodePackagedModules(NPM)を使用して、appサーバーにPM2をインストールします。 次のコマンドを使用して、PM2をインストールします。

  1. sudo npm install pm2@latest -g

PM2のいくつかの基本的な使用法について説明します。

あなたが最初にしたいことは、 pm2 start アプリケーションを実行するコマンド、 hello.js、バックグラウンドで:

  1. 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はアプリ名を自動的に割り当てます(ファイル名に基づいて、 .js 拡張機能)およびPM2 id。 PM2は、プロセスの PID 、その現在のステータス、メモリ使用量などの他の情報も保持します。

PM2で実行されているアプリケーションは、アプリケーションがクラッシュまたは強制終了された場合に自動的に再起動されますが、システムの起動(起動または再起動)時にアプリケーションを起動するには、追加の手順を実行する必要があります。 幸いなことに、PM2はこれを行う簡単な方法を提供します。 startup サブコマンド。

The startup サブコマンドは、サーバーの起動時にPM2とその管理対象プロセスを起動するための起動スクリプトを生成および構成します。 また、実行しているinitシステムを指定する必要があります。 systemd、 私たちの場合には:

  1. 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が起動時に開始するアプリケーションを確実に認識できるようにするには、現在のプロセスリストを保存する必要があります。 リストを保存するには:

  1. pm2 save

次のような出力が表示されます。これは、PM2プロセスリストが保存されたことを示しています。

Output
[PM2] Saving current process list... [PM2] Successfully saved in /home/deployer/.pm2/dump.pm2

これで、PM2管理のアプリケーションが起動時に自動的に起動するはずです。

PM2には、アプリケーションに関する情報を管理または検索できる多くのサブコマンドが用意されています。 実行していることに注意してください pm2 引数なしで、チュートリアルのこのセクションよりも詳細にPM2の使用法をカバーする使用例を含むヘルプページが表示されます。

このコマンドでアプリケーションを停止します(PM2を指定します) App name また id):

  1. pm2 stop example

このコマンドでアプリケーションを再起動します(PM2を指定します) App name また id):

  1. pm2 restart example

PM2によって現在管理されているアプリケーションのリストは、 list サブコマンド:

  1. pm2 list

特定のアプリケーションに関する詳細情報は、を使用して見つけることができます info サブコマンド(PM2アプリ名またはid を指定):

  1. pm2 info example

PM2プロセスモニターは、 monit サブコマンド。 これにより、アプリケーションのステータス、CPU、およびメモリ使用量が表示されます。

  1. pm2 monit

注:PM2を実行しています monit コマンドは、を押してアプリケーションが強制終了されるまで、追加のコマンドをブロックします CTRL+C.

Node.jsアプリケーションが実行され、PM2によって管理されたので、リバースプロキシを設定しましょう。

ステップ4—Nginxリバースプロキシサーバーのセットアップ

アプリケーションが実行され、プライベートIPアドレスをリッスンしているので、ユーザーがアプリケーションにアクセスする方法を設定する必要があります。 この目的のために、リバースプロキシとしてNginxWebサーバーをセットアップします。 このチュートリアルでは、Nginxサーバーを最初からセットアップします。 すでにNginxサーバーをセットアップしている場合は、 location 選択したサーバーブロックにブロックします(場所がWebサーバーの既存のコンテンツと競合しないことを確認してください)。

web サーバーに、 epel-release yumを使用したパッケージ:

  1. sudo yum install epel-release

次に、Nginxをインストールします。

  1. sudo yum install nginx

次に、編集用にNginx構成ファイルを開きます。

  1. sudo vi /etc/nginx/nginx.conf

まず、次の行を見つけます server_name デフォルトのサーバーブロック内で定義されます。 次のようになります。

nginx.confの抜粋— server_name(前)
server_name _;

サーバー名を更新してアンダースコアを置き換えます(_)独自のドメイン名を使用して server_name ディレクティブ(またはドメインが設定されていない場合はIPアドレス)。

nginx.confの抜粋— server_name(後)
server_name your-domain;

次に、次の行を見つけます location / 同じデフォルトのサーバーブロック内で定義されます(通常はserver_nameの数行下)。 次のようになります。

nginx.confの抜粋—場所/(前)
        location / {
        }

次のコードブロックに置き換え、appサーバーのプライベートIPアドレスを必ず置き換えてください。 APP_PRIVATE_IP_ADDRESS. さらに、ポートを変更します(8080)アプリケーションが別のポートでリッスンするように設定されている場合:

/etc/nginx/nginx.confの抜粋—場所/(後)
    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、アクセス http://your-domain/ Webブラウザを介して、ポート上のアプリケーションサーバーのプライベートIPアドレスにリクエストを送信します 8080、Node.jsアプリケーションによって受信および応答されます。

追加できます location 同じサーバーブロックにブロックして、同じwebサーバー上の他のアプリケーションへのアクセスを提供します。 たとえば、ポートのappサーバーで別のNode.jsアプリケーションも実行している場合 8081、このロケーションブロックを追加して、経由でアクセスできるようにすることができます 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-- モード、続いて :wqwritequit 単一のコマンドで。

web サーバーで、Nginxを再起動します。

  1. sudo systemctl start nginx

次に、サーバーが再起動するたびにNginxが実行されるようにします。

  1. sudo systemctl enable nginx

The enable コマンドは次の出力を提供する必要があります

Output
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.

からステータスをリクエストすることで、Nginxが実行中で有効になっていることを確認することもできます systemctl:

  1. 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:

  1. 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ラベル。 次のコマンドを実行すると、この情報を表示できます。

  1. 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_connecthttpd_can_network_relay. Redhatドキュメントには、それぞれの詳細が記載されています。 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.
...

私たちの設定はトラフィックを中継するだけなので、SELinuxに次のことを伝える必要があります httpd サーバー(この場合はNginx)は、ネットワークを使用して、設定したリバースプロキシ構成でトラフィックを中継できます。 を使用します -P フラグ、変更が永続的であることを確認します(このフラグを省略すると、 httpd_can_network_relay サーバーの再起動時にデフォルト状態のオフに戻す):

  1. sudo setsebool -P httpd_can_network_relay on

Node.jsアプリケーションが実行されていて、アプリケーションとNginxの構成が正しいと仮定すると、webサーバーのリバースプロキシを介してアプリケーションにアクセスできるはずです。 web サーバーのURL(パブリックIPアドレスまたはドメイン名)にアクセスして試してみてください。

注: web サーバーを使用して(従来の仮想ホストとして)他のサイトをホストすることも計画している場合は、 httpd_can_network_connect オンに。

結論

これで、Node.jsアプリケーションがNginxリバースプロキシの背後で実行されます。 このリバースプロキシ設定は、共有したい他のアプリケーションや静的Webコンテンツへのアクセスをユーザーに提供するのに十分な柔軟性があります。

また、Webサーバーとユーザー間の送信を暗号化する場合は、 HTTPS(TLS / SSL)サポートを設定するのに役立つチュートリアルがあります