本番前にUbuntu（WSL）でNginxを使ったNext.jsアプリのデプロイ

AWSでNext.jsのアプリをデプロイする前にローカル環境で試してみたかったので、WSLで試しに構築してみました。
まだエンジニアでもない完全初心者なので参考になるかわかりませんがアウトプット兼今後見返すノート的な感じで作成してみました。(2025/1/17)

## 開発環境の準備
まず、最初にパッケージのアップデート、インストールを行います。

以下のコマンドで最新パッケージがあるか確認します。
```
sudo apt update
```
もし更新が確認された場合は
```
sudo apt upgrade
```
で最新に更新します。

次から使うパッケージをインストールしていきます。
以下のコマンドでnpm,Nginxを一気にインストールします。
```
sudo apt install -y npm nginx
```
:::note info
オプション説明
- `-y`はすべてのプロンプトに対して自動で Yes と応答するもの
:::

nodeに関しては、以下のコマンドでNodeSourceレポジトリの追加をすることで、最新バージョンを取得することができます。(Next.jsを使うにはnode.jsもある程度最新でないといけないらしい)

```
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
```
上記のコマンドを実行した後はNode.jsをインストールしていきます。
```
sudo apt-get install -y nodejs
```



## ユーザーの追加
現在まではrootユーザーで実行していたので、これからは新規ユーザーを作成して作業を行っていきます。

以下のコマンドで任意のユーザーを作成します
```
useradd -m <ユーザー名> -s <ログインシェルのパス>

# 例
useradd -m taro -s /bin/bash 
```
:::note info
オプション説明
- `-m`はホームディレクトリを作成してくれる
- `-s`ログインシェルを設定することができる（設定すると便利）
:::
:::note info
いま使っているログインシェルを調べる方法
- `echo $SHELL`で確認可能
:::

次に作成したユーザーのパスワードを設定していきます。

```
passwd <ユーザー名>
```

さらに、今作成したユーザーにsudoを許可していきます。
```
sudo usermod -aG sudo <ユーザー名>
```

ユーザーの変更は以下のコマンドで可能です。
```
su - <ユーザー名>
```
:::note info
ログアウトするには`Ctrl+D`
:::

## Next.jsの実行

ルートユーザから先ほど作ったユーザーの切り替えて、用意してあるNext.jsのプロジェクトをお好みの方法で配置します。
今回はgithubからクローンして配置したいと思います。
```
git clone レポジトリurl
```

ディレクトリを移動してプロジェクトに入り、試しに実行してみましょう。
```
cd <プロジェクトディレクトリ名>
```

プロジェクトで利用しているモジュールをインストールするため、以下のコマンドを実行します。
package.jsonに記載されたモジュールがインストールされます。
```
npm install
```

以下のコマンドを実行することで本番用ビルドを作成します。
```
npm run build
```
ビルドを完了したら、本番用サーバーを起動します。
```
npm start
```

:::note warn
エラーが出てくる際
・セキュリティや依存関係の問題が原因でエラー発生する場合があります。
以下のコードを実行して、潜在的な問題を洗い出すことができます。
```
npm audit 
```
:::

## PM2によるプロセス管理

PM2とはNode.js アプリケーションを管理するためのプロセスマネージャーです。
プロダクション環境でのアプリケーション管理や、アプリケーションの監視、再起動、ロードバランシングなどを簡単に行えるようになります。

以下のコマンドでPM2をインストールしていきます。
```
sudo npm install -g pm2
```
:::note info
オプション説明
- `-g`グローバルインストールをする
:::
:::note info
グローバルインストール
システム全体で利用可能にする方法です。
システム全体にツールがインストールされ、どのディレクトリからでもコマンドを実行できるようになります。
:::

Next.jsのプロジェクトをPM2に登録します。任意のプロセス名を指定します。
```
pm2 start npm --name "<プロセス名>" -- start
```
次にPM2に登録されたプロセスを確認します。以下のコマンドで確認することができます。
この場合先ほど起動した、「プロセス名」がリストのnameに表示されていると思います。
```
pm2 list
```
プロセスを保存するため、以下のコマンドを実行します。
```
pm2 save
```
サーバーが再起動した際も、自動起動するようにしたいので、以下のコマンドを実行して設定していきます。
```
pm2 startup systemd
```
上記のコマンドを実行すると
```
test@PC211111:~/OrderSystem$ pm2 startup systemd
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u test --hp /home/test
```
のようなレスポンスが返ってきますので。sudo付きのコマンドをコピーして実行します。

:::note info
pm2の停止と再開
- 停止
    - `pm2 stop <プロセス名>`
- 再開
    - `pm2 restart <プロセス名>`
:::


## Nginxの設定

Nginxの設定ファイルを作成します。
```
sudo vi /etc/nginx/sites-available/<任意のファイル名>

```
以下の設定をNginxのサイト構成ファイルに追加します。
```
server {
    listen 80;
    server_name your-domain.com; # ドメイン名またはサーバーIPアドレス

    location / {
        proxy_pass http://localhost:3000;
        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;
    }
}
```

次にシンボリックリンクの作成を行います。ファイル名の所には先ほど作成した、設定ファイルの名前。
```
sudo ln -s /etc/nginx/sites-available/<ファイル名> /etc/nginx/sites-enabled/
```

最後にNginxのテストを行います。
```
sudo nginx -t
```
エラーがない場合は
```
test@PC211111:~/OrderSystem$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```
上記のようになるはずです。

設定が正しい場合、Nginx を再起動して変更を反映させます。
```
sudo systemctl restart nginx
```

## 最後に
これで、無事にサーバー（WSL）を再起動しても、自動的にNextで作成したアプリケーションを動くように設定が完了しました。
今回はローカル環境でしか実験していないので、公開するのはまた追加で設定（セキュリティ面でも）が必要だと思いますが、本格的にデプロイする事前学習になると思うので、ぜひ構成してみてください。

## 参考リンク
- Linuxコマンド
    - https://atmarkit.itmedia.co.jp/ait/articles/1811/02/news035.html
    - https://www.sejuku.net/blog/54497
    - https://www.sejuku.net/blog/52175
    - https://eng-entrance.com/linux-command-chsh
- PM2
    - https://qiita.com/ikemura23/items/b3481393d4edca2d5188
    - https://qiita.com/zaburo/items/70a83aee188d45b39e58
- Nginx
    - https://qiita.com/ponponnsan/items/23e1aa6f7dd4eadde5df