Next.jsで作ったアプリをVercelへデプロイしてみます。
今回はVercelのコンソールではなく、Terraformを使用して構築していきます
Vercel コンソールでの設定方法はこちら
Vercelとは??
公式HP
![](https://hisuiblog.com/wp-content/uploads/cocoon-resources/blog-card-cache/addc357ac6701cc5fe40e13f60b343be.png)
Vercelとは、ゼロコンフィグでWEBアプリケーションをデプロイできるサービスです。
Angular、React、Vue など様々なフレームワークに対応しています。
特に、サービスの提供元であるVercel社が開発してるNext.jsを簡単にデプロイできます。
なんと、GitHub等のリポジトリを連携するだけでデプロイでき、
PRをもとにアプリのプレビューを作成したり、自動デプロイが可能です!
本記事のゴール
・Next.jsのアプリを作成し、Vercelにデプロイする。
・ブラウザからアクセスできることを確認する
・自動デプロイできることを確認する。
前提
想定読者
- Node.jsがインストールされている
- Next.jsについて詳細な解説がなくても大丈夫
- GitHubのアカウントがある
- Terraformが使える
本記事で使用しているバージョン
1 2 3 4 5 6 |
~$ npx -version 9.8.1 ~$ npx create-next-app --version 13.4.13 ~$ terraform -v Terraform v1.4.2 |
参考記事
手順が公式ドキュメントにあったので、それを参考にします
また、Terraformの公式ドキュメントやZennの記事も参考にして、進めていきます。
![](https://hisuiblog.com/wp-content/uploads/cocoon-resources/blog-card-cache/6db18e248af5699c9003a7751bc82e59.png)
Next.js のアプリケーション
アプリケーション作成
![](https://vercel.com/api/og/templates?title=Blog%20Starter%20Kit&description=A%20statically%20generated%20blog%20example%20using%20Next.js%20and%20Markdown.&image=https://images.ctfassets.net/e5382hct74si/9HIawEMUBUpmhHTcnFscc/4d16c261512ad87d6cc5fefb32510381/CleanShot_2022-03-09_at_19.30.51.png&framework=Next.js)
こちらのテンプレートを使用してデプロイするアプリを作成します!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
// アプリ作成 ~$ npx create-next-app --example blog-starter sample-blog-nextjs-app Creating a new Next.js app in *********/sample-blog-nextjs-app. Downloading files for example blog-starter. This might take a moment. Installing packages. This might take a couple of minutes. added 215 packages, and audited 216 packages in 48s 89 packages are looking for funding run `npm fund` for details found 0 vulnerabilities Initialized a git repository. Success! Created sample-blog-nextjs-app at *********/sample-blog-nextjs-app Inside that directory, you can run several commands: npm run dev Starts the development server. npm run build Builds the app for production. npm start Runs the built app in production mode. We suggest that you begin by typing: cd sample-blog-nextjs-app npm run dev |
作成出来たら、動作確認しておきましょう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// ディレクトリ移動 ~$ cd sample-blog-nextjs-app // アプリを起動 sample-blog-nextjs-app$ npm run dev > dev > next - ready started server on 0.0.0.0:3000, url: http://localhost:3000 - event compiled client and server successfully in 191 ms (18 modules) - wait compiling / (client and server)... - event compiled client and server successfully in 1948 ms (301 modules) - wait compiling /posts/[slug]... - event compiled client and server successfully in 355 ms (324 modules) ^C sample-blog-nextjs-app$ |
ブラウザから、http://localhost:3000 にアクセスして下記が表示されればOK!
確認ができたら、Ctrl + c でアプリを停止させましょう。
GitHubのリポジトリを作成
![](https://hisuiblog.com/wp-content/uploads/cocoon-resources/blog-card-cache/f543dc43b7b380979be974b14c3fd120.png)
この画面でリポジトリを作成します。
GitHubへpush
リポジトリの画面を参考にGitへpushします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
sample-blog-nextjs-app$ git remote add origin https://github.com/********/sample-blog-nextjs-app.git sample-blog-nextjs-app$ git branch -M main sample-blog-nextjs-app$ git push -u origin main Enumerating objects: 73, done. Counting objects: 100% (73/73), done. Delta compression using up to 16 threads Compressing objects: 100% (65/65), done. Writing objects: 100% (73/73), 308.55 KiB | 11.02 MiB/s, done. Total 73 (delta 6), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (6/6), done. To https://github.com/********/sample-blog-nextjs-app.git * [new branch] main -> main Branch 'main' set up to track remote branch 'main' from 'origin'. |
Vercelでの事前準備
サインアップ
![](https://hisuiblog.com/wp-content/uploads/cocoon-resources/blog-card-cache/e44ccc4c19cb4bb94e3ca3fcbe8890c3.png)
アカウントがない方は、こちらからサインアップしていきます。
今回は試しにデプロイしてみるだけなので、プランは「Hobby」※無料 を選択します。
アカウント名を入力したら、Continue をクリックし次に進みます。
GitHubのリポジトリを使用したいので、「Continue with GitHub」を選択
VercelからGitHubをアクセスできるよう、「Authorize Vercel」をクリックします
アカウントの作成が完了し、ホーム画面(?)に遷移します
VercelからGitHubへアクセスできるようにする
ホーム画面にて、
Import Git Repository > Select a Git Namespace > Add GitHub Account を選択
今回は、先ほど作成したGitHubリポジトリのみをImportしていきます。
「Only select repositories」を選び、Select repositories にてGitHubリポジトリを選択。
選択できたら、Install をクリックします。
GitHubのパスワードを入力すると、ホーム画面に遷移しリポジトリが表示されていればOK!
Tokenを発行する
TerraformからVercelへアクセスできるようTokenを発行しておきます。
手順は公式ドキュメントを参考にします。
![](https://hisuiblog.com/wp-content/uploads/cocoon-resources/blog-card-cache/e44ccc4c19cb4bb94e3ca3fcbe8890c3.png)
こちらにアクセスし、Tokenを発行していきます。
入力情報は下記を参考にし、Create をクリックします。
プロパティ | 説明 | 値 |
TOKEN NAME | Tokenの名前。 わかりやすいものを設定。 |
VERCEL_API_TOKEN |
SCOPE | Tokenの権限。 絞ったほうがいいが、今回はフルでつける。 |
Full Account |
EXPIRATION | Tokenの有効期限。 セキュリティ的には設定したほうが良いが、今回は期限なし。 |
No Expiration |
Tokenが表示されるため、メモしておきます。後ほど使います!
※後からTokenの値を確認できないため、注意
これで事前準備は完了しました!なので、Terraformでコードを書いていきます。
Terraform
ファイルは次のものを作成しました
.
├── deployment.tf
├── main.tf
├── project.tf
├── provider.tf
├── terraform.tfvars
└── variables.tf
コード
main.tf
Vercelを使うことを定義します。
1 2 3 4 5 6 7 8 |
terraform { required_providers { vercel = { source = "vercel/vercel" version = "~> 0.4" } } } |
provider.tf
Vercel 固有の設定をしておきます。今回は先ほど取得したTokenを設定します。
Tokenの値を直書きするのはよくないので、変数を読み取ります。
実際の値は、後ほど出てくるterraform.tfvars に記述します。
1 2 3 |
provider "vercel" { api_token = var.vercel_api_token } |
variables.tf
使う変数を定義します。Vercel Tokenの変数を用意しておきます。
1 |
variable "vercel_api_token" {} |
terraform.tfvars
ここで、VercelのTokenの値を定義します。
1 2 |
# Tokenの値に置き換えてください vercel_api_token = "<Tokenの値>" |
project.tf
Vercelに作成するProjectを定義します
1 2 3 4 5 6 7 8 9 10 |
resource "vercel_project" "example" { name = "sample-blog-nextjs-app" framework = "nextjs" git_repository = { type = "github" # ユーザー名/リポジトリ名は置き換えてください repo = "<ユーザー名/リポジトリ名>" } } |
プロパティ | 説明 |
name
|
プロジェクト名。自分がわかりやすいものなら何でもいい。 |
framework
|
アプリのフレームワーク。 |
git_repository
|
連携させるリポジトリを定義。 |
type
|
GitHub、GitLab、BitBucket のどれと連携させるか。 |
repo
|
連携させるリポジトリ。 |
deployment.tf
デプロイの内容を定義します。
特別なデプロイ設定は今回しないので、これぐらいのプロパティでOKです!
1 2 3 4 5 |
resource "vercel_deployment" "example" { project_id = vercel_project.example.id ref = "main" production = true } |
プロパティ | 説明 |
project_id | デプロイするプロジェクトのID |
ref | デプロイ対象のブランチやコミット。 GitHub、GitLab、BitBucket からデプロイさせる場合は必須。 |
production | 本番環境かどうか |
init
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
~$ terraform init Initializing the backend... Initializing provider plugins... - Finding vercel/vercel versions matching "~> 0.4"... - Installing vercel/vercel v0.15.0... - Installed vercel/vercel v0.15.0 (signed by a HashiCorp partner, key ID ********) Partner and community providers are signed by their developers. If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future. Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary. |
plan
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
~$ terraform plan Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # vercel_deployment.example will be created + resource "vercel_deployment" "example" { + domains = (known after apply) + id = (known after apply) + production = true + project_id = (known after apply) + ref = "main" + team_id = (known after apply) + url = (known after apply) } # vercel_project.example will be created + resource "vercel_project" "example" { + framework = "nextjs" + git_repository = { + production_branch = (known after apply) + repo = "*******/sample-blog-nextjs-app" + type = "github" } + id = (known after apply) + name = "sample-blog-nextjs-app" + protection_bypass_for_automation_secret = (known after apply) + serverless_function_region = (known after apply) + team_id = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now. |
apply
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
~$ terraform apply Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # vercel_deployment.example will be created + resource "vercel_deployment" "example" { + domains = (known after apply) + id = (known after apply) + production = true + project_id = (known after apply) + ref = "main" + team_id = (known after apply) + url = (known after apply) } # vercel_project.example will be created + resource "vercel_project" "example" { + framework = "nextjs" + git_repository = { + production_branch = (known after apply) + repo = "*******/sample-blog-nextjs-app" + type = "github" } + id = (known after apply) + name = "sample-blog-nextjs-app" + protection_bypass_for_automation_secret = (known after apply) + serverless_function_region = (known after apply) + team_id = (known after apply) } Plan: 2 to add, 0 to change, 0 to destroy. Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes vercel_project.example: Creating... vercel_project.example: Creation complete after 1s [id=prj_****************************] vercel_deployment.example: Creating... vercel_deployment.example: Still creating... [10s elapsed] vercel_deployment.example: Still creating... [20s elapsed] vercel_deployment.example: Still creating... [30s elapsed] vercel_deployment.example: Still creating... [40s elapsed] vercel_deployment.example: Creation complete after 49s [id=dpl_****************************] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. |
エラーが出なければOKです!
ブラウザからアクセスして動作確認
https://vercel.com/<アカウント名>/<プロジェクト名>
※アカウント名、プロジェクト名は各々
上記のようなURLからVercelのダッシュボードに遷移し、右上の Visit をクリックします
下記のように表示されればOKです!
自動デプロイ
commit
テスト用のブランチ(test)を切り、checkoutします
1 2 3 4 5 |
sample-blog-nextjs-app$ git checkout -b test Switched to a new branch 'test' sample-blog-nextjs-app$ git branch main * test |
components/intro.tsx に少し変更を加えます(ハイライト部)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import { CMS_NAME } from '../lib/constants' const Intro = () => { return ( <section className="flex-col md:flex-row flex items-center md:justify-between mt-16 mb-16 md:mb-12"> <h1 className="text-5xl md:text-8xl font-bold tracking-tighter leading-tight md:pr-8"> Auto Deploy Test Success!! </h1> <h4 className="text-center md:text-left text-lg mt-5 md:pl-8"> A statically generated blog example using{' '} <a href="https://nextjs.org/" className="underline hover:text-blue-600 duration-200 transition-colors" > Next.js </a>{' '} and {CMS_NAME}. </h4> </section> ) } export default Intro |
commit および push します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
sample-blog-nextjs-app$ git add . sample-blog-nextjs-app$ git commit -m"test_commit" [test a92755f] test_commit 1 file changed, 1 insertion(+), 1 deletion(-) sample-blog-nextjs-app$ git push origin test Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Delta compression using up to 16 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 385 bytes | 385.00 KiB/s, done. Total 4 (delta 3), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (3/3), completed with 3 local objects. remote: remote: Create a pull request for 'test' on GitHub by visiting: remote: https://github.com/********/sample-blog-nextjs-app/pull/new/test remote: To https://github.com/********/sample-blog-nextjs-app.git * [new branch] test -> test |
PRを作成
GitHubのリポジトリの画面からPRを作成していきます
Compare & pull request をクリックします
適当にコメントして、Create pull request をクリックし、PRを作成します
Previewを確認
PRを作成すると、vercel の bot がコメントを残してくれます
そこからPRマージ後のプレビューを確認できます。
Visit Preview をクリックし、下記のように表示されればOKです!
(Auto Deploy Test Success!! と表示されるはず。。。)
コメントを残せるなど、見るだけではなくレビューしやすいものとなっています
PRをマージ
プレビューにて確認できたので、PRをマージしていきます。
Merge pull request → Confirm merge をクリックします。
マージ出来たら、Delete branch でマージ元のブランチを消しておきましょう
自動デプロイを確認
ダッシュボードの Visit からデプロイの結果を確認します。
Created が更新されていれば、デプロイが成功しています。
下記のように表示されればOKです!
(Auto Deploy Test Success!! と表示されるはず。。。)
削除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
~$ terraform destroy vercel_project.example: Refreshing state... [id=prj_****************************] vercel_deployment.example: Refreshing state... [id=dpl_****************************] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # vercel_deployment.example will be destroyed - resource "vercel_deployment" "example" { - domains = [ - "sample-blog-nextjs-app.vercel.app", - "sample-blog-nextjs-app-*******.vercel.app", - "sample-blog-nextjs-app-git-main-*******.vercel.app", ] -> null - id = "dpl_****************************" -> null - production = true -> null - project_id = "prj_****************************" -> null - ref = "main" -> null - url = "sample-blog-nextjs-8ab8svfsc-*******.vercel.app" -> null } # vercel_project.example will be destroyed - resource "vercel_project" "example" { - framework = "nextjs" -> null - git_repository = { - production_branch = "main" -> null - repo = "*******/sample-blog-nextjs-app" -> null - type = "github" -> null } -> null - id = "prj_****************************" -> null - name = "sample-blog-nextjs-app" -> null - serverless_function_region = "iad1" -> null } Plan: 0 to add, 0 to change, 2 to destroy. Do you really want to destroy all resources? Terraform will destroy all your managed infrastructure, as shown above. There is no undo. Only 'yes' will be accepted to confirm. Enter a value: yes vercel_deployment.example: Destroying... [id=dpl_****************************] vercel_deployment.example: Destruction complete after 0s vercel_project.example: Destroying... [id=prj_****************************] vercel_project.example: Destruction complete after 0s Destroy complete! Resources: 2 destroyed. |
まとめ
すごい簡単にデプロイできましたー!!
さらに
- カスタムドメインを使用する
- スピードインサイトを有効にする
などをしていきたいと思いますー。
コメント