🚁

Next.jsをVPS(Vultr)にデプロイする方法(Prisma、PostgreSQL)

2024/10/12に公開

YouTube でゼロから開発するプログラミング動画チュートリアル「フルスタックチャンネル」を発信中の「はる」と申します。

フルスタックチャンネル

Next.js を VPS(Vultr) にデプロイする方法を簡単に紹介します。

Next.js、Prisma(PostgreSQL) を VPS(Vultr) にデプロイする方法になります。

GitHub Actions を使用して、自動デプロイも行います。

Vultr

https://www.vultr.com/?ref=8577994

Vultr(バルチャー)は、クラウドインフラストラクチャを提供するプラットフォームで、主に仮想プライベートサーバー(VPS)を簡単かつ手頃な価格で利用できるサービスです。以下に、Vultr の主な特徴と用途について説明します。

Vultr の特徴

  1. 仮想プライベートサーバー (VPS):
    Vultr は、VPS を提供するサービスです。VPS は、物理サーバーを複数の仮想サーバーに分割し、それぞれを独立したサーバーとして動作させる技術です。これにより、ユーザーは他のサーバーとは独立したリソースを使用でき、自由にソフトウェアやアプリケーションをインストールできます。

  2. グローバルなデータセンター:
    Vultr は、世界中にデータセンターを持っており、ユーザーは自分のビジネスに最適な地域を選んでサーバーをデプロイできます。これにより、エンドユーザーへのアクセスが高速化され、遅延を最小限に抑えることができます。

  3. 手頃な価格とスケーラビリティ:
    Vultr は、低価格なプランを提供しており、必要に応じてサーバーのリソース(CPU、RAM、ストレージ)を簡単にスケールアップできます。最も安いプランから始めて、後から必要に応じてアップグレードすることが可能です。

  4. 使いやすいインターフェース:
    Vultr の管理ダッシュボードは直感的で使いやすく、サーバーの作成、設定、管理を数クリックで行うことができます。また、API も提供されているため、開発者は自動化スクリプトを作成してサーバーの管理を行うことができます。

  5. さまざまな OS のサポート:
    Vultr では、Linux ディストリビューション(Ubuntu、Debian、CentOS など)や Windows のインスタンスを簡単にセットアップできます。また、独自の ISO イメージをアップロードしてカスタム OS をインストールすることも可能です。

Vultr の用途

  1. ウェブサイトホスティング:
    小規模から中規模のウェブサイトやブログ、e コマースサイトをホスティングするのに適しています。サーバーの管理は自由度が高く、コストも抑えられます。

  2. 開発・テスト環境:
    開発者がアプリケーションの開発やテストを行うための環境をすぐにセットアップできます。リソースのスケーリングが簡単なため、プロジェクトの進行に応じてインフラを柔軟に変更できます。

  3. ゲームサーバー:
    Vultr は低レイテンシのデータセンターを提供しているため、オンラインゲームのサーバーをホスティングするのにも適しています。

  4. VPN やセキュリティサーバー:
    自分専用の VPN サーバーを作成したり、ファイアウォールや他のセキュリティソフトウェアをインストールして、セキュアなネットワーク環境を構築することが可能です。

Vultr を利用するメリット

  • 手軽にサーバーを作成: 数分でサーバーを立ち上げられるため、素早くプロジェクトを開始できます。
  • コスト効率: 小規模なプロジェクトから始めて、必要に応じてリソースを増やしていくことができ、費用対効果が高いです。
  • 柔軟性: OS やアプリケーションを自由に選べるため、幅広いニーズに対応できます。

Vultr は、開発者や中小規模の企業、ウェブサイト運営者など、さまざまなユーザーにとって手頃で柔軟なクラウドインフラストラクチャサービスを提供する強力なプラットフォームです。

Vultr アカウント登録

Vultr でアカウントを作成します。

https://www.vultr.com/?ref=8577994

Vultr を使用するには、クレジットカードを登録する必要があります。

登録しても勝手に課金されることはないので安心してください。

メールアドレスの認証もしておいてください。

SSH キー作成

ローカルで SSH キーを作成します。

SSH 鍵ペアは、公開鍵認証を使用して、サーバーへの安全な接続を確立するためのものです。

公開鍵を Vultr に登録し、秘密鍵をローカルに保持します。

公開鍵をサーバーに保存することで、パスワードを使わずにサーバーにログインできるようになります。

この方法は、セキュリティ面でも強力で、特にインターネットに公開されている VPS では必須の設定です。

ssh-keygen -t rsa -b 4096 -C "xxx@gmail.com"

ssh キーを cat コマンドで表示できるので、コピーします。

cat ~/.ssh/id_rsa.pub

SSH キー登録

コピーした ssh キーを Vultr に登録します。

https://my.vultr.com/sshkeys/manage/?id=new

ファイヤーウォール設定

ファイヤーウォールを設定します。

https://my.vultr.com/firewall/add/

escription に適当な名前を入力します。

Vultr のファイヤーウォール設定では、特定のポートだけを開放することが推奨されます。

以下の通信を許可するようにします

  • 22 番は SSH 接続用
  • 80 番は HTTP 通信用
  • 443 番は HTTPS 通信用
  • 5432 番は PostgreSQL の通信用

サーバー作成

ログインしたら、右上のDeployボタンをクリックして、Deploy New Serverでサーバーを作成します。

小規模な個人開発では、このような設定で作成しています。

Deploy Nowをクリックしてサーバーを作成します。

SSH 接続

サーバーが作成されたら、SSH 接続します。

作成されたサーバーに IP アドレス、ユーザー名、パスワードが表示されます。

root ユーザーで SSH 接続します。

ssh root@xxx.xxx.xxx.xxx

ユーザー作成

root ユーザーはセキュリティ上の問題があるため、ユーザーを作成します。

adduser haruyasu

ユーザー権限変更

ユーザーに sudo 権限を付与します。

gpasswd -a haruyasu sudo

ユーザーでログイン

ユーザーでログインします。

su haruyasu

ソフトウェアのインストールとシステムの更新

sudo apt update
sudo apt upgrade
sudo apt install nginx postgresql postgresql-contrib -y

PostgreSQL のデータベース作成

PostgreSQL のデータベースを作成します。

CREATE USER で作成したユーザーに、GRANT ALL PRIVILEGES でデータベース全体の権限を付与しています。

これにより、そのユーザーがデータベースの作成や変更を自由に行えるようになります。

文字コードを UTF-8 に設定することで、国際化対応がスムーズに行えるようにしています。

特に、マルチバイト文字(日本語など)を扱う場合は、UTF-8 の設定が重要です。

haruyasu@vultr:~$ sudo -u postgres psql

postgres=# CREATE DATABASE myproject;
CREATE DATABASE

postgres=# CREATE USER myuser WITH PASSWORD 'password';
CREATE ROLE

postgres=# ALTER ROLE myuser SET client_encoding TO 'utf8';
ALTER ROLE

postgres=# ALTER ROLE myuser SET default_transaction_isolation TO 'read committed';
ALTER ROLE

postgres=# ALTER ROLE myuser SET timezone TO 'UTC+9';
ALTER ROLE

postgres=# GRANT ALL PRIVILEGES ON DATABASE web_matching TO myuser;
GRANT

postgres=# \c myproject
myproject=# GRANT ALL PRIVILEGES ON SCHEMA public TO myuser;
GRANT

postgres=# \q

リポジトリクローン

GitHub からリポジトリをクローンします。

git clone https://github.com/xxxx/myproject.git
cd myproject
git remote set-url origin git@github.com:xxxx/myproject.git

必要であれば、本番環境用のブランチに切り替えます。

git checkout release/production

環境変数作成

.env ファイルを作成します。

nano .env
DATABASE_URL=postgresql://myuser:password@localhost:5432/myproject?schema=public
NEXTAUTH_SECRET=xxxxxx
NEXTAUTH_URL=http://xx.xx.xxx.xxx
NEXT_PUBLIC_APP_URL=http://xx.xx.xxx.xxx

Node.js インストール

https://github.com/nvm-sh/nvm

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm
nvm install --lts
node -v
npm i -g pm2
sudo apt-get update
sudo apt-get install -y nginx
sudo systemctl start nginx
sudo service nginx restart
sudo apt install -y npm
sudo npm install -g pm2

ファイルウォール許可

sudo ufw allow 80
sudo ufw allow 443
sudo ufw reload

この時点で、サーバーの IP アドレスにアクセスして、Welcome to nginx! が表示されることを確認します。

Nginx 設定

Nginx の設定を行って、画面を表示します。

sudo nano /etc/nginx/conf.d/myproject.conf

Nginx はリバースプロキシとして使用され、外部からの HTTP リクエストをアプリケーションに転送します。

特に proxy_pass http://127.0.0.1:3000; の部分では、Next.js アプリケーションが 3000 番ポートで動作していることを想定して、リクエストを適切にルーティングしています。

proxy_set_header で、リクエストヘッダーに関する追加情報を渡す設定が行われていますが、これはセキュリティや正しいリクエスト処理のために重要です。

また、client_max_body_size でクライアントから送信できるデータサイズの上限を設定しており、大きなファイルのアップロードも可能になります。

server {
    listen 80;
    server_name {IPアドレス};
    client_max_body_size 10g;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
sudo nginx -t
sudo systemctl restart nginx

この時点で、IP アドレスにアクセスして、502 Bad Gateway が表示されることを確認します。

セットアップ

Next.js のセットアップを行います。

npm install
npx prisma generate
npx prisma migrate deploy
npm run build
pm2 start 'npm start' --name app
pm2 log

これで、IP アドレスにアクセスして、Next.js の画面が表示されることを確認します。

SSH 公開鍵作成

Github Actions からデプロイをするために、ssh 公開鍵を作成します。

ssh-keygen -t rsa -b 4096 -C "your_email@gmail.com"

# 公開鍵を登録
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

Deploy keys

Github の Settings の Deploy keys に id_rsa.pub の公開鍵を登録します。

設定からSSH and GPG keysをクリックしてアクセスします。

ここに登録しないと、git pull できません。

Github Actions 環境変数

Github の Secret and variables の Actions に環境変数を追加します。

VULTR_HOST
VULTR_USERNAME
VULTR_SSH_KEY

VULTR_SSH_KEY はcat ~/.ssh/id_rsaの中身をコピーして登録します。

出力された内容が-----BEGIN OPENSSH PRIVATE KEY-----から始まり、-----END OPENSSH PRIVATE KEY-----で終わっているか確認してください。

GitHub Actions 設定

GitHub Actions を使用してデプロイを自動化しています。

このフローは、リモートサーバーに変更をデプロイするたびに、手動でサーバーにログインしてコマンドを実行する手間を省きます。

ポイントとしては、以下の流れです:

  1. git pull で最新のコードを取得
  2. npm install で依存パッケージをインストール
  3. npx prisma migrate deploy でデータベースのマイグレーションを適用
  4. アプリケーションを pm2 を使って再起動し、変更を反映

このように、自動化することでデプロイ作業の時間短縮を実現しています。

Github Actions から git pull して、リスタートまでを自動的に実行します。

.github/workflows/deploy.yml

name: Deploy to Vultr Production

on:
  push:
    branches:
      - release/production

jobs:
  build-and-deploy:
    name: Build and Deploy to Vultr
    runs-on: ubuntu-22.04

    steps:
    - name: Checkout to the branch
      uses: actions/checkout@v2

    - name: Deploy to Vultr
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.VULTR_HOST }}
        username: ${{ secrets.VULTR_USERNAME }}
        key: ${{ secrets.VULTR_SSH_KEY }}
        script: |
          ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
          cd /home/dayone/web-matching
          git pull
          npm install
          npx prisma migrate deploy
          npm run build
          pm2 del app
          pm2 start 'npm start' --name app
        ssh_args: '-o StrictHostKeyChecking=no'

release/productionにマージすると、自動的にデプロイされます。

ドメイン取得

お名前.com などでドメインを取得します。

ドメインを取得したら、ネームサーバーの設定からネームサーバーの変更を選択します。

Vultr のネームサーバーを設定します。

ネームサーバー1  ns1.vultr.com
ネームサーバー2  ns2.vultr.com

Vultr DNS 設定

ドメインと IP アドレスを設定します。

https://my.vultr.com/dns/

HTTPS 化

Let's Encrypt を使用します。

sudo apt-get install letsencrypt
sudo systemctl stop nginx
sudo letsencrypt certonly --standalone -d xxxx.com
sudo nano /etc/nginx/conf.d/myproject.conf

nginx の設定を変更します。

server {
    listen 80;
    listen [::]:80;
    server_name xxxx.com;
    return 301 https://$host$request_uri;
}

server {
    listen  443 ssl;
    server_name xxxx.com;
    client_max_body_size 10g;

    ssl_certificate         /etc/letsencrypt/live/xxxx.com/fullchain.pem;
    ssl_certificate_key     /etc/letsencrypt/live/xxxx.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

nginx のチェック

sudo nginx -t
sudo systemctl start nginx

環境変数変更

.envファイルのNEXTAUTH_URLNEXT_PUBLIC_APP_URLを変更します。

NEXTAUTH_URL=https://{ドメイン}
NEXT_PUBLIC_APP_URL=https://{ドメイン}

ビルド

npm run build

pm2 リスタート

pm2 del app
pm2 start 'npm start' --name app

動かない場合

nginx のエラーログを確認します。

sudo tail -f /var/log/nginx/error.log
curl http://127.0.0.1:3000
sudo systemctl restart nginx

証明書自動発行

定期的に証明書を更新するために、cron を使用します。

sudo crontab -e
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
00 05 01 * * sudo systemctl stop nginx; sudo letsencrypt renew; sudo systemctl start nginx

以上で、Next.js アプリケーションを Vultr 上にデプロイする一連の流れを解説しました。

この設定により、自動デプロイや SSL 証明書の自動更新も実現し、安全かつ効率的に運用が可能です。

ソースコード

LINE 登録すると講座のソースコードがダウンロードできます。

新着の講座がいち早く届きますので、ぜひ登録をお願いします。

LINE お友達登録
https://lin.ee/NKoTJnV

フルスタックチャンネル

講座の不明点や個人開発の疑問点など何でもご質問ください。

https://www.fullstackchannel.com/

さらに多くの知識と技術を共有し、また新しい学びの機会を提供することを楽しみにしています。

よろしくお願いします。

Discussion