17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Linkbal(リンクバル)Advent Calendar 2020

Day 10

Nginx,pm2を使ってNuxt.jsの本番環境を構築する

Posted at

はじめに

遅れてしまいましたが、
この記事はLinkbal Advent Calendar 2020の10日目の記事です。

Serverlessについての記事を書こうと思いましたが、準備に間に合わなかったので、このネタは次の記事で書かせていただきます。

本記事はNginx,pm2を使ってNuxt.jsのユニバーサルモードの本番環境を構築することについて紹介したいと思います。

環境

  • Centos 7.x

インストール

まず、以下の必要なものをインストールする

  • Nginx

インストール

$ sudo yum install nginx

自動起動設定

$ sudo systemctl enable nginx
  • Node.js(そして、自分の好みのパッケージマネージャーはyarnですので、yarnもインストールする)

Node.jsのインストール

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
$ . ~/.nvm/nvm.sh
$ nvm
$ nvm install node

Yarnのインストール

$ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
$ sudo yum install yarn
  • pm2: Node.jsのプロセル状態、ログなどを管理するツールです。Nuxt.jsのユニバーサルモードでサーバーサイドレンダリングはNode.jsで動かせるので、このツールを使うべきです。
$ npm install pm2@latest -g

pm2の設定

プロジェクトのディレクトリ内にpm2設定用ecosystem.config.jsファイルを作成する

ecosystem.config.js
module.exports = {
  apps: [
    {
      name: 'nuxt_app',
      cwd: '/path/to/project',
      exec_mode: 'cluster',
      instances: 2,
      script: './node_modules/.bin/nuxt',
      args: 'start -n ./tmp/nuxt_app.sock',
      env: {
	NODE_ENV: 'production'
      }
    }
  ]
}
  • cwd: アプリケーションを動かせるディレクトリ
  • exec_mode: clusterモードで動かせる
  • instances: クラスターのインスタンス数
  • script: アプリケーションを動かせるスクリプトのパス
  • args: scriptの引数です。今回の紹介はTCPじゃなくて、unix socketで動かせます。理由はunix socketの方が効率が高いです。
  • env: アプリケーションで使う環境変数。NODE_ENV: 'production'はNuxtの本番環境モードの設定のためです。

pm2自動起動の設定

最後に、サーバーを再起動した際に、自動にプロセスを再起動するように設定します。

サーバーを再起動した場合、自動にプロセスを再起動する設定は以下のpm2コマンドで実現できます。

$ pm2 startup
$ pm2 save

ですが、Unix Socketで動かせる場合、うまくできなかったです。原因はおそらくpm2再起動の前に、既存のsocketファイルを削除しないといけないことです。

その代わりに、以下の簡単な起動スクリプトを作成して、サーバーの再起動の時に、pm2を再起動させます。

/etc/init.d/nuxt_client
#!/bin/bash
#
#
# description: PM2 next gen process manager for Node.js
# processname: pm2
#
### BEGIN INIT INFO
# Provides:          pm2
# Required-Start:    pm2
# Required-Stop:     
# Should-Start:      
# Should-Stop:
# Default-Start:     
# Default-Stop:
# Short-Description: PM2 init script
# Description: PM2 is the next gen process manager for Node.js
### END INIT INFO

# アプリケーション名
NAME=nuxt_app
# pm2のパス: `which pm2`コマンドでわかります。
PM2="/home/webuser/.nvm/versions/node/v15.4.0/bin/pm2"
# nodeのパス: `which node`コマンドでわかります。
NODE="/home/webuser/.nvm/versions/node/v15.4.0/bin/node"
# pm2を動かせるユーザー
USER=webuser
UNIX_SOCKET_PATH=/path/to/project/tmp/nuxt_app.sock
CONFIG_FILE_PATH=/path/to/project/ecosystem.config.js

start() {
    echo "Starting $NAME"
    su - $USER -c "$PM2 start $CONFIG_FILE_PATH --update-env"
    for i in {0..30}
      do
        echo "Waiting for creating socket file..."
        if [ -e $UNIX_SOCKET_PATH ]; then
            break
        fi
        sleep 1
    done
   # nginxのユーザーもアクセスできるように、権限を設定する
    chmod o+w $UNIX_SOCKET_PATH
}

stop() {
    su - $USER -c "$NODE $PM2 kill"
}

restart() {
    if [ -e $UNIX_SOCKET_PATH ]; then
       rm -rf $UNIX_SOCKET_PATH
    fi
    echo "Restarting $NAME"
    stop
    start
}

reload() {
    echo "Reloading $NAME"
    su - $USER -c "$PM2 reload all"
}

status() {
    echo "Status for $NAME:"
    $NODE $PM2 list
    RETVAL=$?
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        restart
        ;;
    *)
        echo "Usage: {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

自動起動設定

$ sudo chkconfig --add nuxt_client

Nginxの設定

Nginxの簡単な設定は以下のようです。

/etc/nginx/conf.d/nuxt_app.conf
upstream nuxt_client {
  server unix:/path/to/project/tmp/nuxt_app.sock fail_timeout=0;
}

server {
	listen 80;
	server_name example.com;

	index index.html;

	location / {
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header Host $http_host;
		proxy_set_header X-NginX-Proxy true;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
		proxy_pass http://nuxt_client;
	}
}

デプロイ

デプロイするには、capistranoを使います。

deploy.rb
# config valid for current version and patch releases of Capistrano
lock "~> 3.12.1"

set :application, "nuxt_app"
set :repo_url, "リポジトリのURL"
set :deploy_to, "/var/www/nuxt_app"
set :ssh_options, user: 'webuser'

set :branch, ENV['BRANCH'] || 'master'

# build app
after 'deploy:updated', 'init_app:build'
# restart pm2
after 'deploy:publishing', 'init_app:start'

namespace :init_app do
  task :build do
    on roles(:web) do
      execute "cd #{release_path}; yarn install"
      execute "cd #{release_path}; yarn nuxt build"
    end
  end
  task :start do
    on roles(:web) do
      sudo "/etc/init.d/nuxt_client restart"
    end
  end
end

以上です。

リンク

17
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?