NuxtJSをUbuntu/PM2/Nginxでデプロイしよう

今日はNuxtで試しに作ってみたフロントエンドロードマップのウェブアプリをUbuntuサーバーからデプロイします。

先にVueのデプロイの記事を読んでnginxを使ったサーバーを構築しておきましょう。

ちなみにAWS、Heroku, Digital Oceanなどのサーバーを使う場合は今日のようにプロキシサーバーを設定せずにデプロイできる方法があるそうなので見ておいてください。
しかし、今日のNginxの設定はとても良い練習になるのでどのサーバーでも活用してみてください。

準備すること

Nuxtビルドのチョイス

Nuxtアプリをデプロイするにあたり、2つの方法があります。デフォルトはSSR:サーバーサイドレンダリングされる方法で設定されています。もう一つのnpm run generateのコマンドでstaticの静的サイトとしてビルドしたい場合はNuxtのコンフィグに下記のラインを追加しましょう。静的サイトの場合は普通のHTMLファイルのようにそのままデプロイできるのでプロキシサーバーの設定も不要です。

nuxt.config.ts

export default {
  target: 'static'
}

今回はSSRで行います。このような場合はNodeサーバーを使うためPM2でNodeのウェブサーバーを常時起動できるようにしておきます。詳しいPM2の説明は後ほど。

PM2

PM2(プロセスマネージャー2)はビルドインでロードバランスの機能がついているアプリケーションになります。このPM2がNodeJS(今回はNuxtJS)のアプリが365日常に起動されるように監視してくれます。

では、PM2をサーバーにインストールしましょう。もしローカルでLinuxで作業をしている場合は、PM2が起動するアプリを確認できるので同じようにPM2をインストールしてもOKです。

npm install pm2@latest -g
# or
yarn global add pm2

ではNuxtのプロジェクトのルート直下にecosystem.config.jsを作成し、下記の行を追加します。nameの部分は自分のアプリ名に変更しましょう。

module.exports = {
  apps: [
    {
      name: 'NuxtAppName',
      exec_mode: 'cluster',
      instances: 'max',
      script: './.output/server/index.mjs'
    }
  ]
}

次に下記のコマンドでPM2を起動し、NUXTのアプリが登録されるか確認してください。

pm2 start

pm2 ls

実際にサーバーにコードを上げてから同じコマンドを実行します。

リポジトリをクローン

では、UbuntuサーバーにSSHで接続をしたあとに、GitHubのリポジトリからNuxtのプロジェクトをクローンしましょう。もしローカルから直接ファイルを上げたい場合はSFTPなどでアップロードしてください。私はSSHクライアントはいつもMobaXtermを使っています。

sudo apt update
sudo apt install nodejs npm

cd /home/dan/
git clone git@github.com:TraitOtaku/Frondend-Roadmap-Nuxt.git
cd /Frondend-Roadmap-Nuxt/

#パッケージのインストール
npm install

#このコマンドでNuxtがプロダクション用のファイルをコンパイルしてくれます。
npm run build

Nginxのファイルを作成

Nginxをインストールしてコンフィグファイルを作成します。初めての人は理解するまでに時間がかかるかもしれませんが、それぞれのコマンドが何を操作しているのか調べるようにしましょう。

sudo apt install nginx
cd /etc/nginx

#Nginxが指定したフォルダにコンフィグファイルを作成する
sudo nano sites-available/frontend-roadmap

#シンボリックリンクを作成してsites-enabledにファイルを作成する。ここにあるファイルがデプロイ用になる。
sudo ln -s /etc/nginx/sites-available/frontend-roadmap /etc/nginx/sites-enabled/frontend-roadmap

sudo nano sites-available/frontend-roadmap

ではnanoなどのテキストエディタでNginxのコンフィグファイルを書いていきます。ここでとても重要なことを説明します。

今回のデプロイはPM2というプロセスマネージャーを使います。これで、127.0.0.1:3000にNuxtのウェブサーバーを常時起動させます。

それをNginxを使ってプロキシサーバーとしてロカールのPM2のウェブサーバーに飛ばすような形になります。

順番でいうと。。。

  1. ユーザーがドメインにアクセスする。(今回はIPと84番ポート)
  2. Nginxのプロキシサーバーがproxy_passの行を見て指定されたローカルの3000番を返す。
  3. PM2が127.0.0.1:3000でホストされているのでIPから直接アクセスできたように見える。

では、早速nginxのコンフィグを書いていきます。良い慣習としてetx/nginx/sites/available/にサイト名でコンフィグファイルを作成して下記の行を追加します。

map $sent_http_content_type $expires {
    "text/html"                 epoch;
    "text/html; charset=utf-8"  epoch;
    default                     off;
}

server {
   listen 84; #みなさんは理由がない限り80にしてください。
   server_name 172.104.81.40;

   gzip            on;
   gzip_types      text/plain application/xml text/css application/javascript;
   gzip_min_length 1000;

       location / {
        expires $expires;

        proxy_redirect                      off;
        proxy_set_header Host               $host;
        proxy_set_header X-Real-IP          $remote_addr;
        proxy_set_header X-Forwarded-For    $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto  $scheme;
        proxy_read_timeout          1m;
        proxy_connect_timeout       1m;
      proxy_pass                          http://127.0.0.1:3000; # set the address of the Node.js instance here
}

listenはポートになります。通常は80番ポートにしてください。もしユーザーが他のポートでアクセスする場合は普通は、URLの最後にポートが必要になります。例:sankou.com:84

server_nameがホストマシンのIPアドレスです。もしドメインを取得している場合は、代わりにここにドメインを記載します。

proxy_passがPM2のアプリが起動しているURLを記載します。デフォルトで:3000なのでそのままでOKです。

ではNginxのテストをします。

sudo nginx -t

#必要に応じてコンフィグファイルの再読み込み
sudo systemctl reload nginx

OKがでれば問題なしです。

ファイヤーウォール

もし80番ポート以外で設定した場合はポートを開けておくようにしましょう。

ufw status

sudo ufw allow 84/tcp

#80番が空いていない場合
sudo ufw allow 80/tcp
sudo ufw reload

#ファイヤーウォールが起動していない場合
sudo ufw enable

デプロイの確認

これでサイトのデプロイができました。

一応、このような感じになりました。

お疲れ様です。