Next.jsをVPS(Vultr)にデプロイする方法(Prisma、PostgreSQL)
YouTube でゼロから開発するプログラミング動画チュートリアル「フルスタックチャンネル」を発信中の「はる」と申します。
Next.js を VPS(Vultr) にデプロイする方法を簡単に紹介します。
Next.js、Prisma(PostgreSQL) を VPS(Vultr) にデプロイする方法になります。
GitHub Actions を使用して、自動デプロイも行います。
Vultr
Vultr(バルチャー)は、クラウドインフラストラクチャを提供するプラットフォームで、主に仮想プライベートサーバー(VPS)を簡単かつ手頃な価格で利用できるサービスです。以下に、Vultr の主な特徴と用途について説明します。
Vultr の特徴
-
仮想プライベートサーバー (VPS):
Vultr は、VPS を提供するサービスです。VPS は、物理サーバーを複数の仮想サーバーに分割し、それぞれを独立したサーバーとして動作させる技術です。これにより、ユーザーは他のサーバーとは独立したリソースを使用でき、自由にソフトウェアやアプリケーションをインストールできます。 -
グローバルなデータセンター:
Vultr は、世界中にデータセンターを持っており、ユーザーは自分のビジネスに最適な地域を選んでサーバーをデプロイできます。これにより、エンドユーザーへのアクセスが高速化され、遅延を最小限に抑えることができます。 -
手頃な価格とスケーラビリティ:
Vultr は、低価格なプランを提供しており、必要に応じてサーバーのリソース(CPU、RAM、ストレージ)を簡単にスケールアップできます。最も安いプランから始めて、後から必要に応じてアップグレードすることが可能です。 -
使いやすいインターフェース:
Vultr の管理ダッシュボードは直感的で使いやすく、サーバーの作成、設定、管理を数クリックで行うことができます。また、API も提供されているため、開発者は自動化スクリプトを作成してサーバーの管理を行うことができます。 -
さまざまな OS のサポート:
Vultr では、Linux ディストリビューション(Ubuntu、Debian、CentOS など)や Windows のインスタンスを簡単にセットアップできます。また、独自の ISO イメージをアップロードしてカスタム OS をインストールすることも可能です。
Vultr の用途
-
ウェブサイトホスティング:
小規模から中規模のウェブサイトやブログ、e コマースサイトをホスティングするのに適しています。サーバーの管理は自由度が高く、コストも抑えられます。 -
開発・テスト環境:
開発者がアプリケーションの開発やテストを行うための環境をすぐにセットアップできます。リソースのスケーリングが簡単なため、プロジェクトの進行に応じてインフラを柔軟に変更できます。 -
ゲームサーバー:
Vultr は低レイテンシのデータセンターを提供しているため、オンラインゲームのサーバーをホスティングするのにも適しています。 -
VPN やセキュリティサーバー:
自分専用の VPN サーバーを作成したり、ファイアウォールや他のセキュリティソフトウェアをインストールして、セキュアなネットワーク環境を構築することが可能です。
Vultr を利用するメリット
- 手軽にサーバーを作成: 数分でサーバーを立ち上げられるため、素早くプロジェクトを開始できます。
- コスト効率: 小規模なプロジェクトから始めて、必要に応じてリソースを増やしていくことができ、費用対効果が高いです。
- 柔軟性: OS やアプリケーションを自由に選べるため、幅広いニーズに対応できます。
Vultr は、開発者や中小規模の企業、ウェブサイト運営者など、さまざまなユーザーにとって手頃で柔軟なクラウドインフラストラクチャサービスを提供する強力なプラットフォームです。
Vultr アカウント登録
Vultr でアカウントを作成します。
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 に登録します。
ファイヤーウォール設定
ファイヤーウォールを設定します。
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 インストール
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: xxx.xxx.xxx.xxx(VultrのIPアドレス)
VULTR_USERNAME: haruyasu(ユーザー名)
VULTR_SSH_KEY: -----BEGIN OPENSSH PRIVATE KEY-----...
VULTR_SSH_KEY はcat ~/.ssh/id_rsa
の中身をコピーして登録します。
出力された内容が-----BEGIN OPENSSH PRIVATE KEY-----から始まり、-----END OPENSSH PRIVATE KEY-----で終わっているか確認してください。
GitHub Actions 設定
GitHub Actions を使用してデプロイを自動化しています。
このフローは、リモートサーバーに変更をデプロイするたびに、手動でサーバーにログインしてコマンドを実行する手間を省きます。
ポイントとしては、以下の流れです:
- git pull で最新のコードを取得
- npm install で依存パッケージをインストール
- npx prisma migrate deploy でデータベースのマイグレーションを適用
- アプリケーションを 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
にマージすると、自動的にデプロイされます。
ドメイン設定
- ドメイン設定
- サブドメイン設定
0. プラグインインストール
sudo apt update
sudo apt install certbot python3-certbot-nginx
1. ドメイン設定
1-1. DNS レコードの設定
-
ドメイン管理画面にログイン
- お名前.com やその他のドメインレジストラの管理画面にログインします。
-
A レコードの設定
- ドメイン(例:
example.com
)の A レコードに、サーバーの IP アドレス(例:12.34.56.78
)を設定します。 - 他にもメールサービスを利用する場合は、MX レコードの設定も必要です。
- ドメイン(例:
-
ネームサーバーの設定
- Vultr のネームサーバーを設定します。
ネームサーバー1 ns1.vultr.com ネームサーバー2 ns2.vultr.com
1-2. SSL 証明書の取得
-
SSL 証明書の取得
- Nginx が稼働している場合は、以下のコマンドで証明書を取得(
--nginx
プラグインを利用する方法もあります)。
sudo certbot --nginx -d example.com
- Nginx が稼働している場合は、以下のコマンドで証明書を取得(
1-3. サーバー(Nginx)の設定
-
Nginx 設定ファイルの作成・編集
- 例えば、
/etc/nginx/conf.d/example.conf
として以下の内容を作成します。
# HTTP(ポート80): 全てのアクセスをHTTPSにリダイレクト server { listen 80; server_name example.com; client_max_body_size 10g; location / { return 301 https://$host$request_uri; } } # HTTPS(ポート443): SSL証明書を利用した設定 server { listen 443 ssl; server_name example.com; client_max_body_size 10g; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.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 $host; proxy_redirect off; proxy_set_header X-Forwarded-Proto $scheme; } }
- 例えば、
-
Nginx の設定テストと再起動
sudo nginx -t sudo systemctl restart nginx
1-4. SSL 証明書の自動更新
-
自動更新の設定
-
更新用スクリプトの作成
sudo nano /usr/local/bin/renew-letsencrypt.sh
以下の内容を記述します。
※この例では、--pre-hook
と--post-hook
を使い、必要なときだけ Nginx の停止・再起動を行います。#!/bin/bash export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" certbot renew --standalone \ --pre-hook "systemctl stop nginx" \ --post-hook "systemctl start nginx"
-
スクリプトに実行権限を付与
sudo chmod +x /usr/local/bin/renew-letsencrypt.sh
-
Cron ジョブの設定
sudo nano /etc/crontab
以下の行を追加し、毎月 1 日の午前 5 時に自動更新を実行します。
0 5 1 * * root /usr/local/bin/renew-letsencrypt.sh
-
動作確認
sudo /usr/local/bin/renew-letsencrypt.sh
-
2. サブドメイン設定
ここでは、サブドメイン(例: sub.example.com
)の設定方法を説明します。
2-1. DNS レコードの設定
-
DNS 管理画面での設定
- お名前.com などで取得したドメインの場合、管理画面でサブドメインの A レコードを設定します。
- 例:サブドメイン
sub.example.com
の A レコードに、サーバーの IP アドレス(例:12.34.56.78
)を設定します。
-
利用しているサービスによる注意点
-
Vercel を使用している場合:
- サブドメインの A レコードに Vercel の IP アドレスが表示されていれば OK です。
- 表示されない場合は、DNS 設定が正しくない可能性があるため、Vercel の管理画面で A レコードの追加設定を確認してください。
-
Vercel を使用していない場合:
- お名前.com の DNS 管理画面でサブドメインの A レコードを正しく設定します。
-
Vercel を使用している場合:
-
DNS 設定の確認
- Google Toolbox Dig などのオンラインツールで、設定が正しく反映されているか確認します。
2-2. SSL 証明書の取得と自動更新(サブドメイン)
-
証明書の取得
-
サブドメインの場合も、証明書の取得は通常のドメインと同様です。
-
例えば、standalone モードで証明書を取得する場合、以下のように実行します。
sudo systemctl stop nginx sudo letsencrypt certonly --standalone -d sub.example.com
-
注意点:
- 証明書取得前に、ポート 80 が競合していないか確認します。
sudo lsof -i :80 sudo kill -9 [PID]
-
-
自動更新の設定
- 自動更新のスクリプトおよび Cron の設定は、通常のドメイン設定と同様に行います。
- 上記の自動更新用スクリプトを利用して、証明書の有効期限が近づいたときに自動更新が実行されるように設定してください。
2-3. サーバー(Nginx)の設定
-
Nginx 設定ファイルの作成・編集
- 例えば、
/etc/nginx/conf.d/subexample.conf
として以下の内容を作成します。
# HTTP(ポート80):すべてのアクセスをHTTPSにリダイレクト server { listen 80; server_name sub.example.com; client_max_body_size 10g; location / { return 301 https://$host$request_uri; } } # HTTPS(ポート443):SSL証明書を利用した設定 server { listen 443 ssl; server_name sub.example.com; client_max_body_size 10g; ssl_certificate /etc/letsencrypt/live/sub.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/sub.example.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 $host; proxy_redirect off; proxy_set_header X-Forwarded-Proto $scheme; } }
- 例えば、
-
設定のテストと Nginx の再起動
sudo nginx -t sudo systemctl start nginx
環境変数変更
.env
ファイルのNEXTAUTH_URL
、NEXT_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
以上で、Next.js アプリケーションを Vultr 上にデプロイする一連の流れを解説しました。
この設定により、自動デプロイや SSL 証明書の自動更新も実現し、安全かつ効率的に運用が可能です。
ソースコード
LINE 登録すると講座のソースコードがダウンロードできます。
新着の講座がいち早く届きますので、ぜひ登録をお願いします。
LINE お友達登録
フルスタックチャンネル
講座の不明点や個人開発の疑問点など何でもご質問ください。
さらに多くの知識と技術を共有し、また新しい学びの機会を提供することを楽しみにしています。
よろしくお願いします。
Discussion