Nuxt.jsをダウンタイムゼロで本番にデプロイ

nuxtプロジェクトでnpm run buildをすると最初に.nuxt/dist/のファイルが削除されます。そのためビルドしている間アクセスできない状態になってしまい、ダウンタイムが発生してしまいます。

そこで、ダウンタイムゼロでデプロイする方法を備忘録として記載します。

デプロイの流れは以下です。

  • ビルド(npm run build)
  • 起動に必要なファイルをbuildディレクトリにコピー
  • 起動(pm2 start)

手順

pm2を設定

pm2をインストールしていない場合はインストールします。pm2 initでpm2の設定ファイルが作成されます。

// pm2 インストール
$ sudo npm install pm2 -g
// pm2 設定ファイル作成
$ pm2 init

ecosystem.config.jsが作成されます。

デフォルトは以下。

module.exports = {
  apps : [{
    script: 'index.js',
    watch: '.'
  }, {
    script: './service-worker/',
    watch: ['./service-worker']
  }],

  deploy : {
    production : {
      user : 'SSH_USERNAME',
      host : 'SSH_HOSTMACHINE',
      ref  : 'origin/master',
      repo : 'GIT_REPOSITORY',
      path : 'DESTINATION_PATH',
      'pre-deploy-local': '',
      'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
      'pre-setup': ''
    }
  }
};

以下のように修正します。

ecosystem.config.js

module.exports = {
  apps: [
    {
      name: 'app',
      exec_mode: 'cluster', // Or fork 
      instances: 2, // Or a number of instances
      cwd: './build', // only if using a subdirectory
      script: './node_modules/nuxt/bin/nuxt.js',
      args: 'start'
    }
  ]
}

cwdbuildディレクトリで起動するようにします。

instancesは好きな数に設定してください。'max'と記載するとcpuの数に応じて起動します。

scriptで直接node_modules/nuxt/bin/nuxt.jsを叩くように指定しています。

デプロイ用のシェルスクリプト

デプロイ用のシェルスクリプトを作成します。

nuxtの起動に必要なファイルをbuildディレクトリにコピーします。環境によって必要なものをコピーするように記載してください。

今回は以下をコピーした例です。

package.json
.env 
.nuxt/
node_modules/nuxt/
client/nuxt.config.js

deploy.sh

npm install
npm run build

# copy to build dir
mkdir -p build
\cp package.json build/
\cp .env build/
\cp -rf .nuxt build/
mkdir -p build/node_modules
\cp -rf node_modules/nuxt build/node_modules/
mkdir -p build/client
\cp -rf client/nuxt.config.js build/client/

pm2 start

実行します。

$ sh deploy.sh
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ app                │ cluster  │ 1    │ online    │ 0%       │ 31.5mb   │
│ 1  │ app                │ cluster  │ 1    │ online    │ 0%       │ 19.6mb   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

以上です。お疲れ様でした。

参考

Nuxt & PM2: Zero Downtime Deployment | by Xander Luciano | Medium

How to deploy using PM2 cluster mode? – NuxtJS