Next.js CI/CD 実践ガイド:GitHub Actions で実現する自動テストとデプロイ
ターミナルに流れるログを見つめながら、機械的に git pull && npm install && npm run build && pm2 restart と打っていた。今日だけで3回目のデプロイだ——午前は小さなバグ修正、昼は API の最適化、今はスタイルを少し直しただけ。サーバーは3台あり、どれも同じ作業を繰り返す。
最後の1台を終えたとき、時計はすでに7時を回っていた。
その日の帰り道で考えていた。もっと良い方法があるはずだ。コードを直すたびにサーバーで同じ作業を繰り返したくないし、再起動し忘れたサーバーが本番に残る心配もしたくない。テストを忘れてデプロイし、後からバグを見つけてやり直す——そんなこともよくあった。
その後 CI/CD と GitHub Actions に出会い、ワークフローは一変した。GitHub に push するだけで、テスト・ビルド・デプロイまで全部自動だ。コーヒーを淹れているあいだに、新バージョンが公開される。
手動デプロイに苦しんでいるなら、次に GitHub Actions で Next.js の自動デプロイをどう組むかを共有します。基本設定から実践例、私が踏んだ坑と対処まで全部書きます。
なぜ CI/CD が必要なのか
手動デプロイの苦しみ
私が Next.js プロジェクトを始めたばかりの頃、デプロイの手順はこんな感じでした:ローカルでコードを書き、テストし、SSH でサーバーにログインし、git pull でコードを引っぱり、npm install で依存関係を入れ、npm run build でビルドし、最後に pm2 restart でサービスを再起動。順調にいっても十数分はかかります。
しかし、現実はそう順調ではありません。
ある時、3台のサーバーにデプロイしていたのですが、最初の2台は成功したものの、3台目は SSH 接続が切れていて更新されていないことに気づきませんでした。翌日、ユーザーから「サイトが新しいバージョンだったり古いバージョンだったりする」というフィードバックが来ました。ロードバランサーが更新されていないサーバーにリクエストを振り分けていたのです。またある時は、コード修正に興奮してテストをすっ飛ばしてデプロイし、致命的なバグを本番環境に送り込んでしまい、冷や汗をかきながら緊急ロールバックしたこともあります。
さらに厄介なのが、複数サーバーでのビルド問題です。Next.js はビルドごとに新しい build ID を生成します。3台のサーバーでそれぞれビルドすると、ID がバラバラになってしまいます。ロードバランサーがユーザーのリクエストを異なるサーバーに振り分けると、Next.js は ID の変化を検知してハードリフレッシュ(完全な再読み込み)をトリガーしてしまいます。ユーザー体験は最悪です。
CI/CD は何を解決するのか
要するに、CI/CD はこれらの反復的でエラーが発生しやすいプロセスを自動化します。
**CI(継続的インテグレーション)**はテストを担当します。コードをプッシュするたびに、自動的にテスト(単体テスト、型チェック、コード規約チェック)を実行します。テストが通らなければデプロイされません。これにより、バグのあるコードが本番環境に出るのを防げます。
**CD(継続的デプロイ)**はビルドとデプロイを担当します。テストが通れば、自動的にビルドを開始し、完了したらサーバーにデプロイします。この間、指一本動かす必要はありません。
実際の効果は? 私の現在のワークフローはこうです:ローカルでコードを書く → GitHub にプッシュ → 自動テスト → 自動ビルド → 自動デプロイ。プッシュしてから公開まで約5分。その間監視する必要もありません。水を飲みに行って戻ってくれば、新バージョンが公開されています。
もう一つの利点は追跡可能性です。各デプロイには完全なログが残り、どのコミットがトリガーしたか、テスト結果はどうだったか、どのサーバーにデプロイされたかが一目瞭然です。問題が起きてもすぐに原因を特定でき、手探りで調べる必要がありません。
GitHub Actions 基礎設定
仕組みを理解する
GitHub Actions に初めて触れた時、workflow、job、step といった用語に混乱しました。でも実はシンプルです。
**Workflow(ワークフロー)**は一連の自動化プロセス全体を指します。例えば「テスト+ビルド+デプロイ」が1つのワークフローです。これは .github/workflows ディレクトリ内の YAML ファイルで定義します。
**Job(ジョブ)**はワークフロー内の独立したタスクです。例えば「テスト」ジョブと「デプロイ」ジョブを作れます。ジョブは並列実行したり、依存関係を設定して順番に実行したりできます。
**Step(ステップ)**はジョブ内の具体的な操作です。「コードをプルする」「依存関係をインストールする」「テストを実行する」などがステップにあたります。
トリガー条件も柔軟です。main ブランチへのプッシュで実行したり、Pull Request 作成時のみ実行したり、あるいは毎日深夜に自動実行するようスケジュールすることも可能です。
最初の Workflow を作成
まずプロジェクトのルートディレクトリに .github/workflows フォルダを作成し、ci-cd.yml というファイルを作ります。最も基本的な設定は以下のようになります:
name: CI/CD Pipeline
# トリガー条件: main ブランチへの push で実行
on:
push:
branches: [main]
jobs:
build:
# 最新の Ubuntu 環境で実行
runs-on: ubuntu-latest
steps:
# ステップ1: コードを取得
- uses: actions/checkout@v4
# ステップ2: Node.js 環境をセットアップ
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
# ステップ3: 依存関係をインストール
- name: Install dependencies
run: npm ci
# ステップ4: プロジェクトをビルド
- name: Build
run: npm run build
この設定は、「main ブランチにコードがプッシュされるたびに、Ubuntu システム上でコード取得、Node.js 導入、依存インストール、ビルドを実行する」という意味です。
このファイルを GitHub にコミットすると、リポジトリの “Actions” タブでワークフローの実行状況を確認できます。初めてあの緑色のチェックマーク(成功)を見た時は、ちょっとした達成感がありました。
Secrets で機密情報を守る
サーバーへのデプロイには、サーバーの IP、SSH キー、API トークンなどの機密情報が必要です。これらを YAML ファイルに直接書いてはいけません。GitHub にコミットすると世界中に公開されてしまいます。
正しい方法は GitHub の Secrets 機能を使うことです。リポジトリの Settings → Secrets and variables → Actions で “New repository secret” をクリックしてキーを追加します。例えば SERVER_HOST という名前でサーバーの IP アドレスを保存します。
そしてワークフロー内で ${{ secrets.SERVER_HOST }} のように参照します。GitHub は実行時にこれを実際の値に置き換えます。ログ上では伏せ字(***)になり、漏洩することはありません。
自動テストフローの構築
テスト環境の設定
テストに関して私の考えは「自動化できるものは手動でやるな」です。ESLint(コード規約)、TypeScript(型チェック)、Jest(単体テスト)を含むテストフローを構成し、大半の問題をここで食い止めます。
完全なテスト job の設定を見てみましょう:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm' # npm 依存関係をキャッシュして次回以降を高速化
- name: Install dependencies
run: npm ci
- name: Lint check
run: npm run lint
- name: Type check
run: npm run type-check
- name: Run tests
run: npm run test -- --coverage
ここで小技:cache: 'npm' を設定すると自動的に node_modules をキャッシュしてくれるので、2回目以降の実行時に依存関係のダウンロード時間が短縮され、数分の節約になります。
テストフロー高速化のコツ
最初はテストに10分以上かかり、コミットのたびに待つのが苦痛でした。最適化の結果、今では3分で終わります。
コツ1:キャッシュ
npm キャッシュに加え、Next.js のビルドキャッシュも保存します:
- name: Cache Next.js build
uses: actions/cache@v3
with:
path: |
~/.npm
.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}
これで Next.js は変更されたページだけを再ビルドすればよくなり、大幅に速くなります。
コツ2:並列実行
テスト間に依存関係がなければ、複数の job に分割して並列実行できます:
jobs:
lint:
runs-on: ubuntu-latest
steps: [...] # lint だけ実行
test:
runs-on: ubuntu-latest
steps: [...] # 単体テストだけ実行
type-check:
runs-on: ubuntu-latest
steps: [...] # 型チェックだけ実行
これら3つの job は同時に開始されるので、総所要時間は3つの合計ではなく、一番遅い job の時間だけで済みます。
私が踏んだ「地雷」
一度、ローカルではテストが通るのに GitHub Actions では失敗するという事態に陥りました。半日デバッグして分かったのは、GitHub Actions が Pull Request のコードを取得する際、デフォルトで PR ブランチをターゲットブランチにマージした「仮想的なコミット」を作成してチェックアウトするため、ローカルとは微妙に異なる状態になっていたことでした。
解決策は、checkout 時にパラメータを追加することです:
- uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }} # PR ブランチの元のコードを使用
もう一つはテストのタイムアウトです。E2E テストなどは時間がかかるため、デフォルトのタイムアウトでは足りないことがあります。job に長めのタイムアウトを設定しましょう:
jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15 # デフォルトは 6 分
自動デプロイフローの構築
Vercel へのデプロイ:最も簡単な方法
プロジェクトが Vercel にあるなら簡単です。Vercel と GitHub はネイティブに統合されているので、リポジトリを連携するだけで push 時に自動デプロイされます。
しかし、「テストが通った場合のみデプロイしたい」といった細かい制御が必要な場合は、Vercel 公式の GitHub Action を使います:
jobs:
deploy:
runs-on: ubuntu-latest
needs: test # テスト job が完了してから実行
if: github.ref == 'refs/heads/main' # main ブランチのみデプロイ
steps:
- uses: actions/checkout@v4
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-args: '--prod' # 本番環境へデプロイ
Vercel の管理画面で Token を生成し、プロジェクト設定から Org ID と Project ID を取得して GitHub Secrets に保存します。
Vercel の良いところは、PR ごとにプレビュー環境を自動作成してくれる点です。PR を出すと、一時的な環境にデプロイされ、プレビューリンクが発行されるので、変更内容をすぐに確認できて便利です。
自前サーバーへのデプロイ:柔軟だが少し複雑
私自身のプロジェクトは、より自由な制御を求めて自前サーバーに配置しています。この場合、SSH 接続を構成し、GitHub Actions からサーバーコマンドを実行させる必要があります。
まずローカルで SSH キーペアを生成します:
ssh-keygen -t ed25519 -C "github-actions"
公開鍵をサーバーの ~/.ssh/authorized_keys に追加し、秘密鍵を GitHub Secrets(例:SSH_PRIVATE_KEY)に追加します。
そしてデプロイ job を設定します:
jobs:
deploy:
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/my-nextjs-app
git pull origin main
npm install
npm run build
pm2 restart nextjs-app
この設定は、SSH でサーバーに入り、最新コードを取得し、依存関係を入れ、ビルドし、アプリを再起動します。完全に自動化されており、手動ログインは不要です。
複数サーバーでの Build ID 不一致問題の解決
ロードバランシングのために複数台のサーバーにデプロイする場合、重要な問題があります。各サーバーで個別にビルドすると build ID が異なり、ユーザーがアクセスするたびにページがリフレッシュされる問題が発生します。
解決策は「一箇所でビルドし、成果物を配布する」ことです。以下のように設定します:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- run: npm ci
- run: npm run build
# ビルド成果物をアップロード
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: next-build
path: |
.next
public
deploy:
runs-on: ubuntu-latest
needs: build
strategy:
matrix:
server: [server1, server2, server3] # 複数サーバー
steps:
# ビルド成果物をダウンロード
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: next-build
# 各サーバーへデプロイ
- name: Deploy to ${{ matrix.server }}
uses: appleboy/scp-action@master
with:
host: ${{ secrets[format('{0}_HOST', matrix.server)] }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: ".next,public"
target: "/var/www/my-nextjs-app"
これで一度だけビルドを行い、同じ成果物を3台のサーバーに配布するため、build ID が完全に一致します。
最適化とベストプラクティス
ビルドが失敗したらどうするか
自動化は便利ですが、たまに失敗します。ビルドやデプロイが失敗したのに気づかないと、コードはコミットしたのに本番は古いまま、という状態になります。
私は失敗通知を設定しています。メールでも、Slack や DingTalk でも構いません。Slack の例:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
[...デプロイ手順...]
# 失敗時に Slack 通知
- name: Notify on failure
if: failure()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'デプロイ失敗!確認してください。'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
channel: '#deploy-notifications'
これで失敗したら即座に通知が飛んできます。
ブランチ戦略:開発と本番の分離
実際のプロジェクトでは、ブランチごとに環境を分けます。develop はテスト環境、main は本番環境へデプロイする、という構成です。
on:
push:
branches:
- main # 本番環境
- develop # テスト環境
jobs:
deploy-staging:
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- [...テスト環境へのデプロイ...]
deploy-production:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- [...本番環境へのデプロイ...]
普段の開発は develop に push してテスト環境で検証し、問題なければ main にマージして本番へ自動デプロイします。
本番デプロイの前に手動承認を求めるチームもあります。GitHub Actions は job に environment を足し、リポジトリ設定で承認者を指定できます:
jobs:
deploy-production:
runs-on: ubuntu-latest
environment:
name: production # 承認が必要な環境
steps: [...]
本番へデプロイするたびに一度止まり、承認者が「Approve」を押すまで進みません。重要なプロジェクトでは、もう一層の保護になります。
ロールバックの仕組み
テストや承認があっても、本番で問題が出ることはあります。そのときは、すぐ前のバージョンへ戻せる必要があります。
シンプルな案は、デプロイごとに tag を打ち、直近数バージョンのビルド成果物を残しておくことです。戻すときは手動トリガーの workflow で tag を指定します:
on:
workflow_dispatch: # 手動トリガー
inputs:
tag:
description: 'ロールバック先のタグ'
required: true
jobs:
rollback:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.tag }} # 指定タグを使用
- name: Deploy
[...通常のデプロイフロー...]
GitHub Actions の画面から “Run workflow” をクリックし、タグを入力すれば即座にロールバックできます。
環境変数の管理
Next.js プロジェクトでは API URL や DB 接続情報などの環境変数が必要です。これらを Git に入れてはいけません。
- GitHub Secrets に機密情報を保存
- ワークフロー内で環境変数として注入
- Next.js ビルド時に読み込む
- name: Build
run: npm run build
env:
NEXT_PUBLIC_API_URL: ${{ secrets.API_URL }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
これで環境ごとに異なる変数を適用でき、コードの修正は不要です。
実践ケース:完全な設定例
ここまでの話を、ひとつの完全な設定例にまとめます。テスト・ビルド・デプロイの流れを含み、プロジェクトにそのまま流用できる形です:
name: Next.js CI/CD
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# Job 1: コードチェックとテスト
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint check
run: npm run lint
- name: Type check
run: npm run type-check
- name: Run tests
run: npm run test -- --coverage
# Job 2: ビルド
build:
runs-on: ubuntu-latest
needs: test # テスト通過後のみ実行
if: github.event_name == 'push' # PR時はビルドしない
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Cache dependencies and build
uses: actions/cache@v3
with:
path: |
~/.npm
.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
NEXT_PUBLIC_API_URL: ${{ secrets.API_URL }}
# デプロイ用に成果物をアップロード
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: next-build
path: |
.next
public
package.json
# Job 3: テスト環境デプロイ
deploy-staging:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: next-build
- name: Deploy to staging server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.STAGING_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/staging
pm2 stop nextjs-app || true
rm -rf .next public
pm2 start npm --name "nextjs-app" -- start
pm2 save
- name: Notify Slack
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'テスト環境デプロイ ${{ job.status == "success" && "成功" || "失敗" }}'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
# Job 4: 本番環境デプロイ
deploy-production:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
environment:
name: production # 手動承認が必要
steps:
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: next-build
- name: Deploy to production server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.PROD_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd /var/www/production
pm2 stop nextjs-app || true
rm -rf .next public
pm2 start npm --name "nextjs-app" -- start
pm2 save
- name: Notify Slack
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: '本番環境デプロイ ${{ job.status == "success" && "成功" || "失敗" }}'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
この設定では、PR はテストのみ。develop への push でテスト環境へ自動デプロイ、main への push で本番へデプロイ(手動承認あり)。デプロイのたびに Slack へ通知し、失敗もすぐ分かります。
実際に使うときは、GitHub リポジトリの Settings で次の Secrets を用意します:
API_URL: API の URLSTAGING_HOST/PROD_HOST: テスト/本番サーバーのホストSERVER_USER: SSH ユーザー名SSH_PRIVATE_KEY: SSH 秘密鍵SLACK_WEBHOOK: Slack Webhook URL(任意)
設定が終われば、あとはコードを書いて push するだけです。
まとめ
手動デプロイから自動化へ移ると、開発体験は本当に変わります。コードを直すたびにサーバーで同じコマンドを打つ必要も、テスト忘れの不安も、ターミナルを眺めてビルド完了を待つ時間もなくなります。
GitHub Actions で CI/CD を組むには、最初は試行錯誤が要りますが、十分に元が取れます。一度動けば、その後ずっと効いてきます。まずはいちばんシンプルな設定でテストとビルドを通し、デプロイ・通知・ロールバックは少しずつ足していくのがよいです。
振り返ると、以前はどうやって手動デプロイしていたのか、自分でも不思議なほどです。まだ手動の人には、自動化に時間を使う価値があります。push してコーヒーを飲み、戻ったら新バージョンが公開されている——一度味わうと、戻れません。
さっそく試してみてください。Next.js プロジェクトで最初の workflow ファイルを作り、GitHub Actions が緑のチェックを付けた瞬間、言いたいことは伝わるはずです。
Next.js CI/CD 完全設定フロー
GitHub Actions ワークフロー作成からテスト・ビルド・デプロイ設定までの完全な手順
⏱️ 目安時間: 2 時間
- 1
ステップ1: GitHub Actions ワークフロー作成
.github/workflows/deploy.yml を作成:
```yaml
name: Deploy
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install
- run: npm run build
- run: npm test
```
ポイント:
• トリガー条件:main ブランチへの push
• 実行環境:ubuntu-latest
• ステップ:checkout → setup-node → install → build → test - 2
ステップ2: テスト手順の設定
テストステップを追加:
```yaml
- name: Run tests
run: npm test
- name: Type check
run: npm run type-check
- name: Lint
run: npm run lint
```
ポイント:
• テスト失敗でデプロイを阻止
• 型チェックで安全性を確保
• Lint でコード品質を維持
メリット:
• バグのあるコードのデプロイを防止
• 自動実行によりテスト忘れを回避 - 3
ステップ3: ビルド手順の設定
ビルド構成:
```yaml
- name: Build
run: npm run build
env:
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
```
キャッシュ最適化:
```yaml
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
```
ポイント:
• 環境変数の設定
• キャッシュでビルドを高速化
• ビルド出力を確認 - 4
ステップ4: デプロイ手順の設定
SSH デプロイ:
```yaml
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /path/to/app
git pull
npm install
npm run build
pm2 restart app
```
複数サーバーデプロイ:
```yaml
- name: Deploy to servers
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOSTS }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /path/to/app
git pull
npm install
# GitHub Actions でビルドした成果物を使用
pm2 restart app
```
ポイント:
• SSH キー認証を使う
• ビルド ID を統一(GitHub Actions でビルド)
• 複数サーバーでのビルド ID 不一致を避ける
FAQ
なぜ CI/CD が必要なのですか?
• コードを直すたびにサーバーで同じ作業を繰り返す
• サーバーの再起動を忘れやすい
• テストを忘れやすい
• 複数サーバーでのデプロイミス
• ビルド ID の不一致によるハードリフレッシュ
CI/CD の利点:
• テスト・ビルド・デプロイの自動化
• push するだけで公開
• 手動デプロイのミスを防ぐ
• ビルド ID を統一
• 開発効率の向上
実例:
• 3台デプロイで2台成功、3台目は SSH 切断に気づかず未更新
• ロードバランサーが未更新サーバーへ振り分け、ユーザーが旧版を見る
• テストを忘れてデプロイし、本番で致命的バグを発見
解決策:GitHub Actions でフロー全体を自動化する。
GitHub Actions はどう設定しますか?
```yaml
name: Deploy
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install
- run: npm run build
- run: npm test
```
ポイント:
• トリガー:main への push
• 実行環境:ubuntu-latest
• ステップ:checkout → setup-node → install → build → test
Secrets の設定:
• リポジトリ Settings → Secrets
• HOST、USERNAME、SSH_KEY など
• SSH デプロイに使用
提案:まずはシンプルな設定でテストとビルドを通し、デプロイは後から足す。
複数サーバーでビルド ID の不一致をどう防ぎますか?
解決策:ビルド ID を統一する。
GitHub Actions でビルド:
```yaml
- name: Build
run: npm run build
- name: Deploy to servers
uses: appleboy/ssh-action@master
with:
script: |
cd /path/to/app
git pull
# GitHub Actions でビルドした成果物を使う
pm2 restart app
```
または成果物を配布:
```yaml
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: build
path: .next
- name: Deploy to servers
uses: appleboy/ssh-action@master
with:
script: |
# 成果物をダウンロードして配置
```
ポイント:
• GitHub Actions 上で一度だけビルド
• 同じ成果物を各サーバーへ配布
• サーバーごとの個別ビルドを避ける
利点:
• ビルド ID が一致
• ハードリフレッシュを回避
• UX が安定
テストステップはどう設定しますか?
```yaml
- name: Run tests
run: npm test
- name: Type check
run: npm run type-check
- name: Lint
run: npm run lint
```
ポイント:
• テスト失敗でデプロイを止める
• 型チェックで型安全性を確保
• Lint でコード品質を維持
利点:
• 問題のあるコードの本番投入を防ぐ
• 自動実行でテスト忘れを防ぐ
• コード品質の向上
提案:
• まずは最小限のテストから
• カバレッジを段階的に上げる
• テスト品質を継続的に改善
デプロイ通知はどう設定しますか?
```yaml
- name: Notify Slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: 'Deployment completed'
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
```
メール通知:
```yaml
- name: Send email
uses: dawidd6/action-send-mail@v3
with:
to: team@example.com
subject: 'Deployment completed'
body: 'Deployment to production completed successfully'
```
ポイント:
• 成功・失敗の両方を通知
• バージョンや時刻などの情報を含める
• チームへ素早く共有
提案:
• Slack(リアルタイム)
• メール(バックアップ)
• デプロイ詳細を本文に含める
CI/CD のベストプラクティスは?
1. まずテストとビルドを通す
2. 次にデプロイを足す
3. 最後に通知・ロールバック
最初から完璧を目指さず、基本フローを動かしてから拡張する。
継続的改善:
• デプロイ後にログを確認
• 設定を実運用に合わせて調整
• ビルド時間の最適化
• テストカバレッジの向上
主要指標:
• ビルド時間
• テスト合格率
• デプロイ成功率
• ロールバック回数
提案:
• シンプルな設定から始める
• 継続的に改善
• チームで運用
覚えておくこと:CI/CD は一度きりの作業ではなく、継続的なプロセスです。
5分で読めます · 公開日: 2025年12月20日 · 更新日: 2026年6月8日
Next.js 完全ガイド
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
Next.js + Prisma 完全入門ガイド:設定から実践まで(接続リーク対策付き)
Next.js + Prisma の入門チュートリアル。環境構築、Schema 設計、CRUD 実践、ホットリロード時の接続リーク対策まで網羅し、Prisma ORM を素早く使いこなせるようにします。
第 36 / 47 記事
次の記事
Next.js 多言語 SEO 最適化完全ガイド:検索エンジンに各言語を正しくインデックスさせる
多言語サイトの60%以上が SEO 設定に誤りがあります。hreflang タグの設定、多言語 Sitemap の生成、URL 戦略の選択など、よくある落とし穴を避け、各言語版が正しく検索順位を獲得するための核心技術を解説します。
第 38 / 47 記事
関連記事
Next.js App Router 入門ガイド:コア概念と基本操作を解説
Next.js App Router 入門ガイド:コア概念と基本操作を解説
Next.js 15 実践:週末で本番級ブログシステムを構築した方法
Next.js 15 実践:週末で本番級ブログシステムを構築した方法
Next.js Middleware 実践ガイド:パスマッチ、Edge Runtime 制限とよくある落とし穴
コメント
GitHubアカウントでログインしてコメントできます