CentOS7でShipitを使用してNode.js本番環境のデプロイを自動化する方法

提供:Dev Guides
移動先:案内検索

著者は、 Electronic Frontier Foundation を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。

序章

Shipit は、Node.js開発者向けのユニバーサル自動化およびデプロイツールです。 人気のあるOrchestratorパッケージに基づくタスクフロー、 OpenSSH を介したログインとインタラクティブSSHコマンド、および拡張可能なAPIを備えています。 開発者はShipitを使用して、さまざまなNode.jsアプリケーションのビルドおよびデプロイメントワークフローを自動化できます。

Shipitワークフローを使用すると、開発者はタスクを構成するだけでなく、タスクを実行する順序を指定することもできます。 それらを同期的に実行するか非同期的に実行するか、およびどの環境で実行するか。

このチュートリアルでは、ローカル開発環境から本番環境にNode.jsアプリケーションをデプロイするようにShipitをインストールして構成します。 Shipitを使用して、アプリケーションをデプロイし、次の方法でリモートサーバーを構成します。

  • Node.jsアプリケーションのファイルをローカル環境から本番環境に転送します(rsyncgit、およびsshを使用)。
  • アプリケーションの依存関係(ノードモジュール)をインストールします。
  • PM2を使用してリモートサーバーで実行されているNode.jsプロセスを構成および管理します。

前提条件

このチュートリアルを開始する前に、次のものが必要です。

  • 2台のCentOS7サーバー(このチュートリアルでは、appおよびwebという名前になります)は、Node.jsアプリケーションを本番環境にセットアップする方法に従ってプライベートネットワークで構成されます。 CentOS7チュートリアル。
  • CentOS 7チュートリアルでLet'sEncryptを使用してNginxを保護する方法に示されているように、TLS / SSLで保護されたNginx( web サーバー上)。 前提条件を時系列で実行している場合は、 web サーバーで手順1、4、および6を完了するだけでよいことに注意してください。
  • Node.jsとnpmが開発環境にインストールされています。 このチュートリアルでは、バージョン10.17.0を使用します。 これをmacOSまたはUbuntu18.04にインストールするには、Node.jsをインストールしてmacOSにローカル開発環境を作成する方法またはのPPAを使用したインストール]セクションの手順に従います。 Ubuntu18.04にNode.jsをインストールする方法。 Node.jsをインストールすると、npmもインストールされます。 このチュートリアルではバージョン6.11.3を使用します。
  • rsyncおよびgitがインストールされたローカル開発コンピューター。 macOSでは、Homebrewでこれらをインストールできます。 Linuxディストリビューションにgitをインストールするには、「Gitをインストールする方法」チュートリアルに従ってください。
  • GitHubまたは別のホストされているgitサービスプロバイダーのアカウント。 このチュートリアルではGitHubを使用します。

注: Windowsユーザーは、このガイドのコマンドを実行するために、 Windows Subsystem forLinuxをインストールする必要があります。


ステップ1—リモートリポジトリの設定

Shipitでは、ローカル開発マシンとリモートサーバー間で同期するためにGitリポジトリが必要です。 このステップでは、Github.comにリモートリポジトリを作成します。 各プロバイダーはわずかに異なりますが、コマンドは多少転送可能です。

リポジトリを作成するには、WebブラウザでGithub.comを開いてログインします。 ページの右上隅に+の記号があることに気付くでしょう。 + をクリックし、新しいリポジトリをクリックします。

リポジトリの短くて覚えやすい名前を入力します(例:hello-world)。 ここで選択した名前はすべて、ローカルマシンで作業するプロジェクトフォルダーとして複製されることに注意してください。

必要に応じて、リポジトリの説明を追加します。

リポジトリの可視性を、パブリックまたはプライベートのいずれかの好みに設定します。

リポジトリが.gitignoreで初期化されていることを確認し、Add .gitignoreドロップダウンリストからNodeを選択します。 この手順は、不要なファイル(node_modulesフォルダーなど)がリポジトリに追加されないようにするために重要です。

リポジトリの作成ボタンをクリックします。

ここで、リポジトリをGithub.comからローカルマシンに複製する必要があります。

ターミナルを開き、すべてのNode.jsプロジェクトファイルを保存する場所に移動します。 このプロセスにより、現在のディレクトリ内にサブフォルダが作成されることに注意してください。 リポジトリをローカルマシンに複製するには、次のコマンドを実行します。

git clone https://github.com/your-github-username/your-github-repository-name.git

your-github-usernameyour-github-repository-nameを置き換えて、Githubユーザー名と以前に提供されたリポジトリ名を反映する必要があります。

注: Github.comで2要素認証(2FA)を有効にしている場合、コマンドラインでGithubにアクセスするときは、パスワードの代わりに個人アクセストークンまたはSSHキーを使用する必要があります。 2FAに関連するGithubヘルプページには、の詳細情報が記載されています。


次のような出力が表示されます。

OutputCloning into 'your-github-repository-name'...
remote: Enumerating objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
Unpacking objects: 100% (3/3), done.

次のコマンドを実行して、リポジトリに移動します。

cd your-github-repository-name

リポジトリ内には単一のファイルとフォルダーがあり、どちらもGitがリポジトリを管理するために使用するファイルです。 これは次の方法で確認できます。

ls -la

次のような出力が表示されます。

Outputtotal 8
0 drwxr-xr-x   4 asciant  staff  128 22 Apr 07:16 .
0 drwxr-xr-x   5 asciant  staff  160 22 Apr 07:16 ..
0 drwxr-xr-x  13 asciant  staff  416 22 Apr 07:16 .git
8 -rw-r--r--   1 asciant  staff  914 22 Apr 07:16 .gitignore

動作するgitリポジトリを構成したので、展開プロセスを管理するshipit.jsファイルを作成します。

ステップ2—ShipitをNode.jsプロジェクトに統合する

このステップでは、サンプルのNode.jsプロジェクトを作成してから、Shipitパッケージを追加します。 このチュートリアルでは、サンプルアプリ、つまりHTTPリクエストを受け入れてプレーンテキストでHello Worldで応答するNode.jswebサーバーを提供します。 アプリケーションを作成するには、次のコマンドを実行します。

nano hello.js

次のサンプルアプリケーションコードをhello.jsに追加します(APP_PRIVATE_IP_ADDRESS変数をapp サーバーのプライベートネットワークIPアドレスに更新します)。

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/');

次に、アプリケーション用のpackage.jsonファイルを作成します。

npm init -y

このコマンドは、Node.jsアプリケーションの構成に使用するpackage.jsonファイルを作成します。 次の手順では、npmコマンドラインインターフェイスを使用してこのファイルに依存関係を追加します。

OutputWrote to ~/hello-world/package.json:
{
  "name": "hello-world",
  "version": "1.0.0",
  "description": "",
  "main": index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

次に、次のコマンドを使用して、必要なnpmパッケージをインストールします。

npm install --save-dev shipit-cli shipit-deploy shipit-shared

Shipitパッケージはローカルマシンでのみ必要であるため、ここでは--save-devフラグを使用します。 次のような出力が表示されます。

Output+ [email protected]
+ [email protected]
+ [email protected]
updated 4 packages and audited 21356 packages in 11.671s
found 62 low severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details

これにより、開発の依存関係として3つのパッケージがpackage.jsonファイルに追加されました。

package.json

. . .
  "devDependencies": {
    "shipit-cli": "^4.2.0",
    "shipit-deploy": "^4.1.4",
    "shipit-shared": "^4.4.2"
  },
. . .

ローカル環境を構成したら、Shipitベースの展開用にリモートappサーバーの準備に進むことができます。

ステップ3—リモートアプリサーバーの準備

この手順では、sshを使用してアプリサーバーに接続し、リモート依存関係rsyncをインストールします。 Rsyncは、ファイルの変更時間とサイズを比較することにより、ローカルコンピュータードライブ間およびネットワークコンピューター間でファイルを効率的に転送および同期するためのユーティリティです。

Shipitは、rsyncを使用して、ローカルコンピューターとリモートのappサーバー間でファイルを転送および同期します。 rsyncに直接コマンドを発行することはありません。 Shipitがあなたに代わってそれを処理します。

ノート: CentOS7で本番用にNode.jsアプリケーションを設定する方法 left you with two servers アプリ and ウェブ. These commands should be executed on アプリ only.


sshを介してリモートappサーバーに接続します。

ssh deployer@your_app_server_ip

次のコマンドを実行して、サーバーにrsyncをインストールします。

sudo yum install rsync

次のコマンドでインストールを確認します。

rsync --version

このコマンドの出力内に同様の行が表示されます。

Outputrsync  version 3.1.2  protocol version 31
. . .

exitと入力すると、sshセッションを終了できます。

rsyncがインストールされ、コマンドラインで使用できるようになっていると、展開タスクとそれらのイベントとの関係に進むことができます。

ステップ4—デプロイメントタスクの構成と実行

イベントタスクはどちらもShipitデプロイメントの主要コンポーネントであり、それらがアプリケーションのデプロイメントをどのように補完するかを理解することが重要です。 Shipitによってトリガーされるイベントは、展開ライフサイクルの特定のポイントを表します。 Shipitライフサイクルのシーケンスに基づいて、これらのイベントに応答してタスクが実行されます。

このタスク/イベントシステムがNode.jsアプリケーションで役立つ一般的な例は、リモートサーバーへのアプリの依存関係(node_modules)のインストールです。 このステップの後半で、Shipitにupdatedイベント(アプリケーションのファイルが転送された後に発行される)をリッスンさせ、タスクを実行してアプリケーションの依存関係(npm install)をリモートにインストールします。サーバ。

イベントをリッスンしてタスクを実行するには、リモートサーバー( app サーバー)に関する情報を保持し、イベントリスナーとこれらのタスクによって実行されるコマンドを登録する構成ファイルが必要です。 このファイルは、Node.jsアプリケーションのディレクトリ内のローカル開発コンピューターにあります。

開始するには、リモートサーバー、サブスクライブするイベントリスナー、およびタスクの定義に関する情報を含むこのファイルを作成します。 次のコマンドを実行して、ローカルマシンのアプリケーションルートディレクトリ内にshipitfile.jsを作成します。

nano shipitfile.js

ファイルを作成したので、Shipitが必要とする初期環境情報をファイルに入力する必要があります。 これは主にリモートGitリポジトリの場所であり、重要なのは、appサーバーのパブリックIPアドレスとSSHユーザーアカウントです。

この初期構成を追加し、強調表示された行を環境に合わせて更新します。

shipitfile.js

module.exports = shipit => {
  require('shipit-deploy')(shipit);
  require('shipit-shared')(shipit);

  const appName = 'hello';

  shipit.initConfig({
    default: {
      deployTo: '/home/sammy/your-domain',
      repositoryUrl: 'https://git-provider.tld/YOUR_GIT_USERNAME/YOUR_GIT_REPO_NAME.git',
      keepReleases: 5,
      shared: {
        overwrite: true,
        dirs: ['node_modules']
      }
    },
    production: {
      servers: 'sammy@YOUR_APP_SERVER_PUBLIC_IP'
    }
  });

  const path = require('path');
  const ecosystemFilePath = path.join(
    shipit.config.deployTo,
    'shared',
    'ecosystem.config.js'
  );

  // Our listeners and tasks will go here

};

shipit.initConfigメソッドの変数を更新すると、Shipitにデプロイメントに固有の構成が提供されます。 これらは、Shipitにとって次のことを表しています。

  • deployTo:は、Shipitがアプリケーションのコードをリモートサーバーにデプロイするディレクトリです。 ここでは、sudo特権(/home/sammy)を持つ非rootユーザーの/home/フォルダーを使用します。これは安全であり、アクセス許可の問題を回避します。 /your-domainコンポーネントは、ユーザーのホームフォルダー内の他のフォルダーとフォルダーを区別するための命名規則です。
  • repositoryUrl:は完全なGitリポジトリへのURLです。ShipitはこのURLを使用して、デプロイ前にプロジェクトファイルが同期されていることを確認します。
  • keepReleases:は、リモートサーバーに保持するリリースの数です。 releaseは、リリース時のアプリケーションのファイルを含む日付がスタンプされたフォルダーです。 これらは、展開のrollbackに役立ちます。
  • shared:は、keepReleasesに対応する構成であり、リリース間でディレクトリをsharedにすることができます。 この例では、すべてのリリース間で共有される単一のnode_modulesフォルダーがあります。
  • production:は、アプリケーションをデプロイするリモートサーバーを表します。 この例では、productionという名前の単一のサーバー( app サーバー)があり、servers:構成はSSHuserおよびpublic ip addressproductionという名前は、このチュートリアルの最後で使用されるShipitデプロイコマンド(npx shipit server name deployまたはこの場合はnpx shipit production deploy)に対応しています。

Shipit Deploy Configuration オブジェクトの詳細については、ShipitGithubリポジトリを参照してください。

shipitfile.jsの更新を続行する前に、次のサンプルコードスニペットを確認して、Shipitタスクを理解しましょう。

Example event listenershipit.on('deploy', () => {
  shipit.start('say-hello');
});

shipit.blTask('say-hello', async () => {
  shipit.local('echo "hello from your local computer"')
});

これは、shipit.onメソッドを使用してdeployイベントをサブスクライブするタスクの例です。 このタスクは、deployイベントがShipitライフサイクルによって発行されるのを待ち、イベントが受信されると、タスクはshipit.startメソッドを実行して、Shipitにstartを通知します。 say-helloタスク。

shipit.onメソッドは、リッスンするイベントの名前と、イベントの受信時に実行するコールバック関数の2つのパラメーターを取ります。

shipit.onメソッド宣言では、タスクはshipit.blTaskメソッドで定義されます。 これにより、実行中に他のタスクをブロックする新しいShipitタスクが作成されます(これは同期タスクです)。 shipit.blTaskメソッドも、定義しているタスクの名前と、タスクがshipit.startによってトリガーされたときに実行するコールバック関数の2つのパラメーターを取ります。

このサンプルタスクのコールバック関数(say-hello)内で、shipit.localメソッドはローカルマシンでコマンドを実行します。 ローカルコマンドは、"hello from your local computer"を端末出力にエコーします。

リモートサーバーでコマンドを実行する場合は、shipit.remoteメソッドを使用します。 shipit.localshipit.remoteの2つのメソッドは、デプロイメントの一部としてローカルまたはリモートでコマンドを発行するためのAPIを提供します。

次に、shipitfile.jsを更新して、shipit.onでShipitライフサイクルにサブスクライブするイベントリスナーを含めます。 イベントリスナーをshipitfile.jsに追加し、初期構成// Our tasks will go hereのコメントプレースホルダーの後に挿入します。

shipitfile.js

. . .
  shipit.on('updated', () => {
    shipit.start('npm-install', 'copy-config');
  });

  shipit.on('published', () => {
    shipit.start('pm2-server');
  });

これらの2つのメソッドは、Shipit展開ライフサイクルの一部として発行されるupdatedおよびpublishedイベントをリッスンします。 イベントが受信されると、サンプルタスクと同様に、それぞれがshipit.startメソッドを使用してタスクを開始します。

リスナーをスケジュールしたので、対応するタスクを追加します。 次のタスクをshipitfile.jsに追加し、イベントリスナーの後に挿入します。

shipitfile.js

. . .
shipit.blTask('copy-config', async () => {

const fs = require('fs');

const ecosystem = `
module.exports = {
apps: [
  {
    name: '${appName}',
    script: '${shipit.releasePath}/hello.js',
    watch: true,
    autorestart: true,
    restart_delay: 1000,
    env: {
      NODE_ENV: 'development'
    },
    env_production: {
      NODE_ENV: 'production'
    }
  }
]
};`;

  fs.writeFileSync('ecosystem.config.js', ecosystem, function(err) {
    if (err) throw err;
    console.log('File created successfully.');
  });

  await shipit.copyToRemote('ecosystem.config.js', ecosystemFilePath);
});

最初にcopy-configというタスクを宣言します。 このタスクは、ecosystem.config.jsというローカルファイルを作成し、そのファイルをリモートのappサーバーにコピーします。 PM2は、このファイルを使用してNode.jsアプリケーションを管理します。 PM2に必要なファイルパス情報を提供して、最新のデプロイ済みファイルが実行されていることを確認します。 ビルドプロセスの後半で、ecosystem.config.jsを構成としてPM2を実行するタスクを作成します。

アプリケーションで環境変数(データベース接続文字列など)が必要な場合は、 [を設定するのと同じ方法で、env:でローカルに、またはenv_production:でリモートサーバーで宣言できます。 X210X]これらのオブジェクトの変数。

copy-configタスクに続いて、次のタスクをshipitfile.jsに追加します。

shipitfile.js

. . .
shipit.blTask('npm-install', async () => {
  shipit.remote(`cd ${shipit.releasePath} && npm install --production`);
});

次に、npm-installというタスクを宣言します。 このタスクは、リモートbashターミナル(shipit.remote経由)を使用して、アプリの依存関係(npmパッケージ)をインストールします。

npm-installタスクに続いて、最後のタスクをshipitfile.jsに追加します。

shipitfile.js

. . .
shipit.blTask('pm2-server', async () => {
  await shipit.remote(`pm2 delete -s ${appName} || :`);
  await shipit.remote(
    `pm2 start ${ecosystemFilePath} --env production --watch true`
  );
});

最後に、pm2-serverというタスクを宣言します。 このタスクでは、リモートbashターミナルを使用して、最初にPM2deleteコマンドを使用して以前のデプロイメントを管理するのを停止し、次にecosystem.config.jsを提供するNode.jsサーバーの新しいインスタンスを開始します。 ]変数としてのファイル。 また、PM2に、初期構成でproductionブロックの環境変数を使用する必要があることを通知し、PM2にアプリケーションを監視するように依頼し、アプリケーションがクラッシュした場合は再起動します。

完全なshipitfile.jsファイル:

shipitfile.js

module.exports = shipit => {
  require('shipit-deploy')(shipit);
  require('shipit-shared')(shipit);

  const appName = 'hello';

  shipit.initConfig({
    default: {
      deployTo: '/home/deployer/example.com',
      repositoryUrl: 'https://git-provider.tld/YOUR_GIT_USERNAME/YOUR_GIT_REPO_NAME.git',
      keepReleases: 5,
      shared: {
        overwrite: true,
        dirs: ['node_modules']
      }
    },
    production: {
      servers: 'deployer@YOUR_APP_SERVER_PUBLIC_IP'
    }
  });

  const path = require('path');
  const ecosystemFilePath = path.join(
    shipit.config.deployTo,
    'shared',
    'ecosystem.config.js'
  );

  // Our listeners and tasks will go here
  shipit.on('updated', async () => {
    shipit.start('npm-install', 'copy-config');
  });

  shipit.on('published', async () => {
    shipit.start('pm2-server');
  });

  shipit.blTask('copy-config', async () => {
    const fs = require('fs');
    const ecosystem = `
module.exports = {
  apps: [
    {
      name: '${appName}',
      script: '${shipit.releasePath}/hello.js',
      watch: true,
      autorestart: true,
      restart_delay: 1000,
      env: {
        NODE_ENV: 'development'
      },
      env_production: {
        NODE_ENV: 'production'
      }
    }
  ]
};`;

    fs.writeFileSync('ecosystem.config.js', ecosystem, function(err) {
      if (err) throw err;
      console.log('File created successfully.');
    });

    await shipit.copyToRemote('ecosystem.config.js', ecosystemFilePath);
  });

  shipit.blTask('npm-install', async () => {
    shipit.remote(`cd ${shipit.releasePath} && npm install --production`);
  });

  shipit.blTask('pm2-server', async () => {
    await shipit.remote(`pm2 delete -s ${appName} || :`);
    await shipit.remote(
      `pm2 start ${ecosystemFilePath} --env production --watch true`
    );
  });
};

準備ができたら、ファイルを保存して終了します。

shipitfile.jsを構成し、イベントリスナー、および関連するタスクを完了したら、appサーバーへのデプロイに進むことができます。

ステップ5—アプリケーションのデプロイ

このステップでは、アプリケーションをリモートで展開し、展開によってアプリケーションがインターネットで利用できるようになったことをテストします。

ShipitはリモートGitリポジトリからプロジェクトファイルを複製するため、ローカルNode.jsアプリケーションファイルをローカルマシンからGithubにプッシュする必要があります。 Node.jsプロジェクトのアプリケーションディレクトリ(hello.jsshiptitfile.jsが配置されている場所)に移動し、次のコマンドを実行します。

git status

git statusコマンドは、作業ディレクトリとステージング領域の状態を表示します。 どの変更がステージングされているか、どの変更がステージングされていないか、どのファイルがGitによって追跡されていないかを確認できます。 ファイルは追跡されておらず、出力に赤で表示されます。

OutputOn branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    hello.js
    package-lock.json
    package.json
    shipitfile.js

nothing added to commit but untracked files present (use "git add" to track)

次のコマンドを使用して、これらのファイルをリポジトリに追加できます。

git add --all

このコマンドは出力を生成しませんが、git statusを再度実行すると、コミットする変更があることに注意して、ファイルが緑色で表示されます。

次のコマンドを実行してコミットを作成できます。

git commit -m "Our first commit"

このコマンドの出力は、ファイルに関するGit固有の情報を提供します。

Output[master c64ea03] Our first commit
 4 files changed, 1948 insertions(+)
 create mode 100644 hello.js
 create mode 100644 package-lock.json
 create mode 100644 package.json
 create mode 100644 shipitfile.js

残っているのは、Shipitがデプロイ中にappサーバーにクローンを作成するためにコミットをリモートリポジトリにプッシュすることだけです。 次のコマンドを実行します。

git push origin master

出力には、リモートリポジトリとの同期に関する情報が含まれます。

OutputEnumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 8 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 15.27 KiB | 7.64 MiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To github.com:Asciant/hello-world.git
   e274312..c64ea03  master -> master

アプリケーションをデプロイするには、次のコマンドを実行します。

npx shipit production deploy

このコマンドの出力(全体を含めるには大きすぎる)は、実行されているタスクと特定の機能の結果の詳細を提供します。 pm2-serverタスクの次の出力は、Node.jsアプリが起動されたことを示しています。

OutputRunning 'deploy:init' task...
Finished 'deploy:init' after 432 μs
. . .
Running 'pm2-server' task...
Running "pm2 delete -s hello || :" on host "centos-ap-app.asciant.com".
Running "pm2 start /home/deployer/example.com/shared/ecosystem.config.js --env production --watch true" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com [PM2][WARN] Node 4 is deprecated, please upgrade to use pm2 to have all features
@centos-ap-app.asciant.com [PM2][WARN] Applications hello not running, starting...
@centos-ap-app.asciant.com [PM2] App [hello] launched (1 instances)
@centos-ap-app.asciant.com ┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────────┬──────────┐
@centos-ap-app.asciant.com │ App name │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user     │ watching │
@centos-ap-app.asciant.com ├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────────┼──────────┤
@centos-ap-app.asciant.com │ hello    │ 0  │ 1.0.0   │ fork │ 4177 │ online │ 0       │ 0s     │ 0%  │ 4.5 MB   │ deployer │ enabled  │
@centos-ap-app.asciant.com └──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────────┴──────────┘
@centos-ap-app.asciant.com  Use `pm2 show <id|name>` to get more details about an app
Finished 'pm2-server' after 5.27 s

Running 'deploy:clean' task...
Keeping "5" last releases, cleaning others
Running "(ls -rd /home/deployer/example.com/releases/*|head -n 5;ls -d /home/deployer/example.com/releases/*)|sort|uniq -u|xargs rm -rf" on host "centos-ap-app.asciant.com".
Finished 'deploy:clean' after 1.81 s

Running 'deploy:finish' task...
Finished 'deploy:finish' after 222 μs
Finished 'deploy' [ deploy:init, deploy:fetch, deploy:update, deploy:publish, deploy:clean, deploy:finish ]

アプリケーションをユーザーのように表示するには、ブラウザにWebサイトのURL your-domainを入力して、webサーバーにアクセスします。 これにより、ファイルがデプロイされた app サーバー上で、リバースプロキシを介してNode.jsアプリケーションが提供されます。

HelloWorldの挨拶が表示されます。

注:最初のデプロイ後、Gitリポジトリはecosystem.config.jsという名前の新しく作成されたファイルを追跡します。 このファイルはデプロイごとに再構築され、コンパイルされたアプリケーションシークレットが含まれている可能性があるため、次のgitコミットの前に、ローカルマシンのアプリケーションルートディレクトリにある.gitignoreファイルに追加する必要があります。

.gitignore

. . .
# ecosystem.config
ecosystem.config.js

Node.jsアプリケーションをappサーバーにデプロイしました。これは、新しいデプロイメントを指します。 すべてが稼働している状態で、アプリケーションプロセスの監視に進むことができます。

ステップ6—アプリケーションの監視

PM2は、リモートプロセスを管理するための優れたツールですが、これらのアプリケーションプロセスのパフォーマンスを監視する機能も提供します。

次のコマンドを使用して、SSH経由でリモートappサーバーに接続します。

ssh deployer@your_app_server_ip

PM2管理対象プロセスに関連する特定の情報を取得するには、以下を実行します。

pm2 list

次のような出力が表示されます。

Output┌─────────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬──────┬───────────┬──────────┬──────────┐
│ App name    │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu  │ mem       │ user     │ watching │
├─────────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼──────┼───────────┼──────────┼──────────┤
│ hello       │ 0  │ 0.0.1   │ fork │ 3212 │ online │ 0       │ 62m    │ 0.3% │ 45.2 MB   │ deployer │ enabled  │
└─────────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴──────┴───────────┴──────────┴──────────┘

PM2が収集した情報の概要が表示されます。 詳細情報を表示するには、次のコマンドを実行できます。

pm2 show hello

出力は、pm2 listコマンドによって提供される要約情報を拡張したものです。 また、いくつかの補助コマンドに関する情報を提供し、ログファイルの場所を提供します。

Output  Describing process with id 0 - name hello
┌───────────────────┬─────────────────────────────────────────────────────────────┐
│ status            │ online                                                      │
│ name              │ hello                                                       │
│ version           │ 1.0.0                                                       │
│ restarts          │ 0                                                           │
│ uptime            │ 82s                                                         │
│ script path       │ /home/deployer/example.com/releases/20190531213027/hello.js │
│ script args       │ N/A                                                         │
│ error log path    │ /home/deployer/.pm2/logs/hello-error.log                    │
│ out log path      │ /home/deployer/.pm2/logs/hello-out.log                      │
│ pid path          │ /home/deployer/.pm2/pids/hello-0.pid                        │
│ interpreter       │ node                                                        │
│ interpreter args  │ N/A                                                         │
│ script id         │ 0                                                           │
│ exec cwd          │ /home/deployer                                              │
│ exec mode         │ fork_mode                                                   │
│ node.js version   │ 4.2.3                                                       │
│ node env          │ production                                                  │
│ watch & reload    │ ✔                                                           │
│ unstable restarts │ 0                                                           │
│ created at        │ 2019-05-31T21:30:48.334Z                                    │
└───────────────────┴─────────────────────────────────────────────────────────────┘
 Revision control metadata
┌──────────────────┬────────────────────────────────────────────────────┐
│ revision control │ git                                                │
│ remote url       │ N/A                                                │
│ repository root  │ /home/deployer/example.com/releases/20190531213027 │
│ last update      │ 2019-05-31T21:30:48.559Z                           │
│ revision         │ 62fba7c8c61c7769022484d0bfa46e756fac8099           │
│ comment          │ Our first commit                                   │
│ branch           │ master                                             │
└──────────────────┴────────────────────────────────────────────────────┘
 Divergent env variables from local env
┌───────────────────────────┬───────────────────────────────────────┐
│ XDG_SESSION_ID            │ 15                                    │
│ HOSTNAME                  │ N/A                                   │
│ SELINUX_ROLE_REQUESTED    │                                       │
│ TERM                      │ N/A                                   │
│ HISTSIZE                  │ N/A                                   │
│ SSH_CLIENT                │ 44.222.77.111 58545 22                │
│ SELINUX_USE_CURRENT_RANGE │                                       │
│ SSH_TTY                   │ N/A                                   │
│ LS_COLORS                 │ N/A                                   │
│ MAIL                      │ /var/mail/deployer                    │
│ PATH                      │ /usr/local/bin:/usr/bin               │
│ SELINUX_LEVEL_REQUESTED   │                                       │
│ HISTCONTROL               │ N/A                                   │
│ SSH_CONNECTION            │ 44.222.77.111 58545 209.97.167.252 22 │
└───────────────────────────┴───────────────────────────────────────┘
. . .

PM2は、次の方法でアクセスできる端末内監視ツールも提供します。

pm2 monit

このコマンドの出力はインタラクティブなダッシュボードであり、pm2はリアルタイムのプロセス情報、ログ、メトリック、およびメタデータを提供します。 このダッシュボードは、リソースとエラーログの監視に役立つ場合があります。

Output┌─ Process list ────────────────┐┌─ Global Logs ─────────────────────────────────────────────────────────────┐
│[ 0] hello     Mem:  22 MB     ││                                                                           │
│                               ││                                                                           │
│                               ││                                                                           │
└───────────────────────────────┘└───────────────────────────────────────────────────────────────────────────┘
┌─ Custom metrics (http://bit.l─┐┌─ Metadata ────────────────────────────────────────────────────────────────┐
│ Heap Size              10.73  ││ App Name              hello                                               │
│ Heap Usage             66.14  ││ Version               N/A                                                 │
│ Used Heap Size          7.10  ││ Restarts              0                                                   │
│ Active requests            0  ││ Uptime                55s                                                 │
│ Active handles             4  ││ Script path           /home/asciant/hello.js                              │
│ Event Loop Latency      0.70  ││ Script args           N/A                                                 │
│ Event Loop Latency p95        ││ Interpreter           node                                                │
│                               ││ Interpreter args      N/A                                                 │
└───────────────────────────────┘└───────────────────────────────────────────────────────────────────────────┘

PM2を使用してプロセスを監視する方法を理解したら、Shipitが以前の作業展開へのロールバックを支援する方法に進むことができます。

exitを実行して、appサーバーでsshセッションを終了します。

ステップ7—バグのある展開をロールバックする

展開により、予期しないバグや、サイトの障害を引き起こす問題が発生することがあります。 Shipitの開発者とメンテナーはこれを予期しており、アプリケーションの以前の(機能している)デプロイメントにロールバックする機能を提供しています。

PM2構成を確実に維持するには、rollbackイベントのshipitfile.jsに別のイベントリスナーを追加します。

shipitfile.js

. . .
  shipit.on('rollback', () => {
    shipit.start('npm-install', 'copy-config');
  });

rollbackイベントにリスナーを追加して、npm-installおよびcopy-configタスクを実行します。 これが必要なのは、publishedイベントとは異なり、展開をロールバックするときにupdatedイベントがShipitライフサイクルによって実行されないためです。 このイベントリスナーを追加すると、ロールバックが発生した場合でも、PM2プロセスマネージャーが最新のデプロイメントを指すようになります。

このプロセスはデプロイに似ていますが、コマンドが少し変更されています。 以前のデプロイメントにロールバックするために、以下を実行できます。

npx shipit production rollback

deployコマンドと同様に、rollbackは、ロールバックプロセスと実行中のタスクの詳細を提供します。

OutputRunning 'rollback:init' task...
Get current release dirname.
Running "if [ -h /home/deployer/example.com/current ]; then readlink /home/deployer/example.com/current; fi" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com releases/20190531213719
Current release dirname : 20190531213719.
Getting dist releases.
Running "ls -r1 /home/deployer/example.com/releases" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com 20190531213719
@centos-ap-app.asciant.com 20190531213519
@centos-ap-app.asciant.com 20190531213027
Dist releases : ["20190531213719","20190531213519","20190531213027"].
Will rollback to 20190531213519.
Finished 'rollback:init' after 3.96 s

Running 'deploy:publish' task...
Publishing release "/home/deployer/example.com/releases/20190531213519"
Running "cd /home/deployer/example.com && if [ -d current ] && [ ! -L current ]; then echo "ERR: could not make symlink"; else ln -nfs releases/20190531213519 current_tmp && mv -fT current_tmp current; fi" on host "centos-ap-app.asciant.com".
Release published.
Finished 'deploy:publish' after 1.8 s

Running 'pm2-server' task...
Running "pm2 delete -s hello || :" on host "centos-ap-app.asciant.com".
Running "pm2 start /home/deployer/example.com/shared/ecosystem.config.js --env production --watch true" on host "centos-ap-app.asciant.com".
@centos-ap-app.asciant.com [PM2][WARN] Node 4 is deprecated, please upgrade to use pm2 to have all features
@centos-ap-app.asciant.com [PM2][WARN] Applications hello not running, starting...
@centos-ap-app.asciant.com [PM2] App [hello] launched (1 instances)
@centos-ap-app.asciant.com ┌──────────┬────┬─────────┬──────┬──────┬────────┬─────────┬────────┬─────┬──────────┬──────────┬──────────┐
@centos-ap-app.asciant.com │ App name │ id │ version │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem      │ user     │ watching │
@centos-ap-app.asciant.com ├──────────┼────┼─────────┼──────┼──────┼────────┼─────────┼────────┼─────┼──────────┼──────────┼──────────┤
@centos-ap-app.asciant.com │ hello    │ 0  │ 1.0.0   │ fork │ 4289 │ online │ 0       │ 0s     │ 0%  │ 4.5 MB   │ deployer │ enabled  │
@centos-ap-app.asciant.com └──────────┴────┴─────────┴──────┴──────┴────────┴─────────┴────────┴─────┴──────────┴──────────┴──────────┘
@centos-ap-app.asciant.com  Use `pm2 show <id|name>` to get more details about an app
Finished 'pm2-server' after 5.55 s

Running 'deploy:clean' task...
Keeping "5" last releases, cleaning others
Running "(ls -rd /home/deployer/example.com/releases/*|head -n 5;ls -d /home/deployer/example.com/releases/*)|sort|uniq -u|xargs rm -rf" on host "centos-ap-app.asciant.com".
Finished 'deploy:clean' after 1.82 s

Running 'rollback:finish' task...
Finished 'rollback:finish' after 615 μs
Finished 'rollback' [ rollback:init, deploy:publish, deploy:clean, rollback:finish ]

shipitfile.jskeepReleases: 5構成を介して5つのリリースを保持するようにShipitを構成しました。 Shipitはこれらのリリースを内部で追跡し、必要なときにロールバックできるようにします。 Shipitは、タイムスタンプ(YYYYMMDDHHmmss-例:/home/deployer/your-domain/releases/20190420210548)という名前のディレクトリを作成することにより、リリースを識別する便利な方法も提供します。

ロールバックプロセスをさらにカスタマイズしたい場合は、ロールバック操作に固有のイベントをリッスンできます。 次に、これらのイベントを使用して、ロールバックを補完するタスクを実行できます。 Shipitライフサイクルの内訳で提供されるイベントリストを参照し、shipitfile.js内でタスク/リスナーを構成できます。

ロールバックできるということは、デプロイメントによって予期しないバグや問題が発生した場合でも、機能しているバージョンのアプリケーションを常にユーザーに提供できることを意味します。

結論

このチュートリアルでは、いくつかのサーバーから、Platform asaServiceの高度にカスタマイズ可能な代替手段を作成できるワークフローを構成しました。 このワークフローにより、カスタマイズされた展開と構成、PM2を使用したプロセスの監視、サービスの拡張と追加の可能性、または必要に応じて展開にサーバーや環境を追加できます。

Node.jsスキルの開発を継続することに興味がある場合は、DigtalOceanNode.jsコンテンツNode.jsシリーズのコーディング方法を確認してください。