Next.js: 最終プロジェクト: デプロイと CI/CD

最終更新:2026-08-26

コードのコミットからユーザーのブラウザに届くまでには、デプロイ、CI/CD、監視、パフォーマンス最適化といういくつかのステップがあります — これがアプリケーションを真に「稼働」させるための最後のステップです。

1. 学習内容



2. ある DevOps エンジニアの実話

(1) 課題:毎回のデプロイが「地雷を踏む」ようなもの

Diana は Acme Corp の DevOps エンジニアで、TaskFlow のデプロイと運用を担当しています。チームは月に 20 回デプロイしますが、毎回のデプロイが神経をすり減らす体験です:SSH で手動アップロードしたコードで環境変数が欠落し(本番データベースに接続できなくなる)、npm run build はローカルでは動くのにサーバーで OOM(メモリ不足)エラーが発生し、ユーザーエラーはデプロイ後 2 時間経つまで発見されず(監視アラートがない)、Lighthouse スコアが 85 から 62 に下がったことにも誰も気づきませんでした。直近のデプロイでは 30 分の停止が発生し、カスタマーサービスに 200 件以上の苦情が寄せられました。

(2) 自動 CI/CD + デュアルデプロイ + 監視のソリューション

GitHub Actions で品質チェックを自動化 + Vercel でゼロ設定デプロイ + セルフホスト Docker の代替案 + PostHog/Sentry による包括的な監視。

YAML
# 1 行の GitHub Actions で完全自動デプロイをトリガー
name: Deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - uses: amondnet/vercel-action@v20

(3) 成果

項目 手動デプロイ CI/CD 自動化
デプロイ時間 45 分(手動チェック含む) 8 分(完全自動)
停止リスク 高い(ファイル欠落/設定誤り) 低い(一貫性保証)
問題発見 2 時間後にユーザーが苦情 Sentry がリアルタイムアラート
Lighthouse スコア 月 1 回手動実行 PR ごとに自動検出
ロールバック速度 15 分手動復元 1 分 Vercel ロールバック
チーム効率 DevOps ボトルネック セルフサービスデプロイ


3. Vercel へのデプロイ

(1) Vercel アーキテクチャ

100%
graph TB
    subgraph "Vercel エッジネットワーク"
        A[グローバル CDN] --> B[エッジ関数]
        B --> C[サーバーレス関数]
        C --> D[Vercel Postgres]
    end

    subgraph "GitHub"
        E[ソースコード] -->|プッシュ| F[GitHub Actions]
        F -->|自動デプロイ| A
    end

    subgraph "監視"
        G[Vercel Analytics]
        H[Sentry]
        I[PostHog]
    end

    C --> G
    C --> H
    B --> I

    style A fill:#cce5ff
    style E fill:#d4edda
    style F fill:#ffeeba

▶ サンプル: vercel.json 設定

💻 出力:

TEXT 📖 参照専用
キーを含む JSON 設定: framework ("nextjs")、buildCommand、outputDirectory、installCommand、regions (iad1/hkg1/gru1)、env、crons、headers(セキュリティヘッダー + キャッシュルール)、redirects。
JSON
{
  "framework": "nextjs",
  "buildCommand": "npm run build",
  "outputDirectory": ".next",
  "installCommand": "npm install",
  "regions": ["iad1", "hkg1", "gru1"],
  "env": {
    "NEXT_PUBLIC_APP_URL": "https://taskflow.vercel.app"
  },
  "crons": [
    {
      "path": "/api/cron/daily-digest",
      "schedule": "0 8 * * *"
    }
  ],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-XSS-Protection",
          "value": "1; mode=block"
        },
        {
          "key": "Referrer-Policy",
          "value": "strict-origin-when-cross-origin"
        }
      ]
    },
    {
      "source": "/uploads/(.*)",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=31536000, immutable"
        }
      ]
    }
  ],
  "redirects": [
    {
      "source": "/app",
      "destination": "/dashboard",
      "permanent": true
    }
  ]
}
💻 出力:

TEXT 📖 参照専用
JSON 設定が正常に適用されました。

▶ サンプル: Vercel CLI を使用したデプロイ

💻 出力:

TEXT 📖 参照専用
コマンドが完了しました。
BASH
# 1. Vercel CLI のインストール
npm install -g vercel

# 2. Vercel にログイン
vercel login

# 3. プロジェクトの関連付け
vercel link

# 4. 環境変数の設定
vercel env add DATABASE_URL
vercel env add AUTH_SECRET
vercel env add GOOGLE_CLIENT_ID
vercel env add GOOGLE_CLIENT_SECRET
vercel env add AUTH_URL
vercel env add NEXT_PUBLIC_POSTHOG_KEY
vercel env add SENTRY_DSN

# 5. プレビューデプロイ
vercel

# 6. 本番デプロイ
vercel --prod

# 7. デプロイログの表示
vercel logs
💻 出力:

TEXT 📖 参照専用
127 パッケージが 3.2 秒で追加されました

38 パッケージが資金提供を求めています
  詳細は `npm fund` を実行してください
環境変数が設定されました。
環境変数が設定されました。
環境変数が設定されました。
環境変数が設定されました。
環境変数が設定されました。
環境変数が設定されました。
環境変数が設定されました。
TEXT 📖 参照専用
Vercel CLI 28.0.0
? "C:\Users\admin\taskflow" をセットアップしてデプロイしますか? [Y/n] Y
? どのスコープですか? Acme Corp
? 既存のプロジェクトにリンクしますか? いいえ
? プロジェクト名は何ですか? taskflow
? コードはどのディレクトリにありますか? ./
自動検出されたプロジェクト設定 (Next.js):
- ビルドコマンド: npx next build
- 出力ディレクトリ: .next
- Node.js バージョン: 20.x
✅ 本番: https://taskflow.vercel.app [7s]

▶ サンプル: Vercel Postgres への接続

BASH
# 1. Postgres データベースの作成
vercel env add DATABASE_URL

# 2. Vercel Postgres SDK のインストール
npm install @vercel/postgres

# 3. Prisma データソースの更新
PRISMA
// prisma/schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
  // Vercel Postgres の自動接続プール管理
  // Vercel では、マイグレーション競合を避けるために shadowDatabaseUrl を有効にします
}
💻 出力:

TEXT 📖 参照専用
Prisma スキーマが更新されました。npx prisma generate を実行してクライアントを同期してください。
TYPESCRIPT
// src/lib/db.ts
import { PrismaClient } from "@prisma/client"

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClient | undefined
}

export const prisma = globalForPrisma.prisma ?? new PrismaClient()

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma


4. セルフホスト Docker

(1) セルフホストアーキテクチャ

100%
graph TB
    subgraph "Docker ホスト"
        A[Nginx<br/>リバースプロキシ] --> B[Node.js アプリ<br/>(PM2)]
        B --> C[PostgreSQL<br/>(コンテナ)]
    end

    subgraph "外部"
        D[DNS: taskflow.example.com]
    end

    D --> A
    A -->|SSL 終端| B

    style A fill:#d4edda
    style B fill:#cce5ff
    style C fill:#f8d7da

▶ サンプル: Dockerfile のマルチステージビルド

💻 出力:

TEXT 📖 参照専用
ビルドコンテキストを Docker デーモンに送信しています  4.096kB
Step 1/8 : FROM node:20-alpine AS deps
 ---> 1dd67de0f936
...
Successfully built a7b3c2d1e0f9
Successfully tagged taskflow:latest
DOCKERFILE
# ============================================
# ステージ 1: 依存関係
# ============================================
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --only=production --ignore-scripts
RUN npm ci --only=development --ignore-scripts

# ============================================
# ステージ 2: ビルド
# ============================================
FROM node:20-alpine AS builder
WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production
ENV NEXT_OUTPUT=standalone

RUN npx prisma generate
RUN npm run build

# ============================================
# ステージ 3: 本番ランナー
# ============================================
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma

USER nextjs

EXPOSE 3000

ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]
💻 出力:

TEXT 📖 参照専用
ビルドコンテキストを Docker デーモンに送信しています  4.096kB
Step 1/8 : FROM node:20-alpine AS deps
 ---> 1dd67de0f936
...
Successfully built a7b3c2d1e0f9
Successfully tagged taskflow:latest

▶ サンプル: docker-compose.yml

💻 出力:

TEXT 📖 参照専用
上記の YAML 設定を指定されたファイルパスに保存してください。設定は次回のサーバー再起動時に有効になります。
YAML
version: "3.8"

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgresql://taskflow:password@db:5432/taskflow
      - AUTH_SECRET=${AUTH_SECRET}
      - AUTH_URL=https://taskflow.example.com
      - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}
      - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
      - NEXTAUTH_URL=https://taskflow.example.com
      - NODE_ENV=production
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      - taskflow-network
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  db:
    image: postgres:16-alpine
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=taskflow
      - POSTGRES_USER=taskflow
      - POSTGRES_PASSWORD=${DB_PASSWORD}
    ports:
      - "5432:5432"
    restart: unless-stopped
    networks:
      - taskflow-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U taskflow"]
      interval: 10s
      timeout: 5s
      retries: 5

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
    depends_on:
      - app
    restart: unless-stopped
    networks:
      - taskflow-network

volumes:
  postgres-data:

networks:
  taskflow-network:
    driver: bridge
💻 出力:

TEXT 📖 参照専用
設定セクション: version、services、volumes、networks。

▶ サンプル: Nginx 設定

💻 出力:

TEXT 📖 参照専用
セクション: version、services、volumes、networks。
NGINX
# nginx.conf
events {
  worker_connections 1024;
}

http {
  upstream taskflow_app {
    server app:3000;
  }

  server {
    listen 80;
    server_name taskflow.example.com;
    return 301 https://$server_name$request_uri;
  }

  server {
    listen 443 ssl http2;
    server_name taskflow.example.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # セキュリティヘッダー
    add_header X-Frame-Options "DENY" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Gzip 圧縮
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
    gzip_min_length 1000;
    gzip_comp_level 6;

    # 静的アセット(永続キャッシュ)
    location /_next/static {
      proxy_pass http://taskflow_app;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      expires 365d;
      add_header Cache-Control "public, immutable";
    }

    # アップロード
    location /uploads {
      proxy_pass http://taskflow_app;
      proxy_set_header Host $host;
      expires 30d;
      add_header Cache-Control "public, immutable";
    }

    # API ルート(キャッシュなし)
    location /api {
      proxy_pass http://taskflow_app;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_no_cache 1;
      proxy_cache_bypass 1;
    }

    # その他すべて
    location / {
      proxy_pass http://taskflow_app;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      # WebSocket サポート
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
  }
}
💻 出力:

TEXT 📖 参照専用
Nginx 設定が適用されました。リロードして有効化してください。


5. GitHub Actions CI/CD

(1) パイプラインアーキテクチャ

100%
graph LR
    A[main にプッシュ] --> B[Lint]
    B --> C[型チェック]
    C --> D[ユニットテスト]
    D --> E[ビルド]
    E --> F[Vercel にデプロイ]
    F --> G[Lighthouse CI]
    G --> H{スコア >= 90?}
    H -->|はい| I[成功]
    H -->|いいえ| J[ロールバック]

    style A fill:#cce5ff
    style F fill:#d4edda
    style G fill:#ffeeba
    style J fill:#f8d7da


6. 本番監視

(1) 監視アーキテクチャ

100%
graph TB
    subgraph "ユーザー指標"
        A["PostHog<br/>イベント & ファネル"]
        B["Vercel Speed Insights<br/>リアルユーザー監視"]
    end

    subgraph "エラートラッキング"
        C["Sentry<br/>エラー & パフォーマンス"]
    end

    subgraph "パフォーマンス"
        D["Lighthouse CI<br/>スコアトレンド"]
        E["Bundle Analyzer<br/>バンドルサイズ"]
    end

    subgraph "アラート"
        F["Sentry アラート<br/>PagerDuty"]
        G["GitHub チェック<br/>PR コメント"]
    end

    A --> F
    B --> D
    C --> F
    D --> G
    E --> G

    style A fill:#d4edda
    style B fill:#cce5ff
    style C fill:#f8d7da


7. パフォーマンス最適化

(1) 最適化戦略の比較

戦略 指標 最適化前 最適化後 ツール
next/image lazy LCP 3.2s 1.5s <Image loading="lazy">
バンドル分割 TTI 4.5s 2.8s @next/bundle-analyzer
フォント最適化 CLS 0.25 0.02 next/font display:swap
PPR 静的シェル FCP 2.1s 0.4s experimental.ppr
画像 CDN LCP 2.8s 1.2s Vercel Image Optimization
キャッシング戦略 TTFB 800ms 120ms revalidateTag + CDN


8. 完全な例: 本番環境でのデプロイと検証

BASH
# ============================================
# TaskFlow 完全本番デプロイプロセス
# ============================================

# --- プラン A: Vercel デプロイ ---

# 1. ビルド前チェック
npm run lint && npx tsc --noEmit && npm run test -- --run

# 2. ビルドと検証
npm run build
# 出力: ✓ 12.8 秒で正常にコンパイルされました

# 3. プレビューデプロイ
vercel
# 出力: https://taskflow-git-feature-abc123.vercel.app

# 4. E2E テストの実行
npx playwright test --url=https://taskflow-git-feature-abc123.vercel.app

# 5. Lighthouse チェック
npx lhci autorun

# 6. 本番デプロイ
vercel --prod
# 出力: https://taskflow.vercel.app (本番)

# 7. カスタムドメインの設定
vercel domains add taskflow.example.com
# 出力: ✓ ドメイン taskflow.example.com が追加されました

# 8. 検証
curl -I https://taskflow.example.com/api/health
# 出力: HTTP/2 200

# --- プラン B: Docker セルフホスト ---

# 1. Docker イメージのビルド
docker build -t taskflow:latest .

# 2. サービスの起動
docker compose up -d

# 3. データベースマイグレーションの実行
docker compose exec app npx prisma migrate deploy

# 4. シードの実行
docker compose exec app npx prisma db seed

# 5. 検証
curl http://localhost/api/health
# 出力: {"status":"healthy","timestamp":"2026-07-06T10:00:00Z"}

# 6. ログの表示
docker compose logs -f app

# 7. 監視指標
# - PostHog: https://app.posthog.com/project/taskflow
# - Sentry: https://sentry.io/organizations/acme/projects/taskflow
# - Vercel ダッシュボード: https://vercel.com/acme/taskflow

# --- パフォーマンス検証 ---

# Lighthouse レポート
# パフォーマンス: 94/100 ✅
# アクセシビリティ: 97/100 ✅
# ベストプラクティス: 93/100 ✅
# SEO: 100/100 ✅

# Core Web Vitals (RUM)
# LCP: 1.2s ✅ (目標 < 2.5s)
# FID: 12ms ✅ (目標 < 100ms)
# CLS: 0.02 ✅ (目標 < 0.1)


9. 学習パスの振り返りと発展トピック

(1) Next.js 16 フルスタック学習ロードマップ

100%
graph TB
    subgraph "フェーズ 1: 基礎 (6 レッスン)"
        A1["01-02: 導入 + 環境"]
        A2["03-04: ルーティング + レイアウト"]
        A3["05-06: ナビゲーション + 並列ルート"]
    end

    subgraph "フェーズ 2: データ (7 レッスン)"
        B1["07-08: RSC + データ収集"]
        B2["09-10: SSG/ISR/PPR"]
        B3["11-12: キャッシュ + Server Actions"]
        B4["13-14: Actions 応用 + API ルート"]
    end

    subgraph "フェーズ 3: 応用 (6 レッスン)"
        C1["15: 認証 Auth.js"]
        C2["16: データベース Prisma"]
        C3["17: ストリーミング"]
        C4["18: 画像/フォント"]
        C5["19: SEO/メタデータ"]
        C6["20: i18n/ミドルウェア"]
    end

    subgraph "フェーズ 4: 本番 (6 レッスン)"
        D1["21-22: ユニット + E2E テスト"]
        D2["23-24: CI/CD + Docker"]
        D3["25-26: パフォーマンス + セキュリティ/移行"]
    end

    subgraph "フェーズ 5: 総合プロジェクト (4 レッスン)"
        E1["27: 初期化 + 認証"]
        E2["28: ダッシュボード + PPR"]
        E3["29: CRUD + Server Actions"]
        E4["30: デプロイ + CI/CD + 監視"]
    end

    A1 --> A2 --> A3 --> B1
    B1 --> B2 --> B3 --> B4 --> C1
    C1 --> C2 --> C3 --> C4 --> C5 --> C6 --> D1
    D1 --> D2 --> D3 --> E1
    E1 --> E2 --> E3 --> E4

    style A1 fill:#d4edda
    style E4 fill:#cce5ff

(2) スキル一覧

スキル 対応レッスン 習熟度
App Router ファイルシステムルーティング #03–#06 熟達
サーバーコンポーネント思考 #07 熟達
データ取得とキャッシング #08–#11 熟達
Server Actions CRUD #12-#13, #29 熟達
認証と認可 #15, #27 習熟
Prisma ORM データベース #16, #27 習熟
テスト(Vitest + Playwright) #21-#22 習熟
CI/CD パイプライン #23, #30 習熟
Vercel + Docker デュアルデプロイ #24, #30 習熟
パフォーマンス監視と最適化 #25, #30 習熟
セキュリティと移行 #26 学習
PPR + キャッシュコンポーネント #10-#11 熟達(独自)

(3) さらなる学習領域

トピック 学習内容 推奨リソース
AI 統合 Vercel AI SDK + RAG + ストリーミング vercel/ai (10k⭐)
マイクロフロントエンド Module Federation + Turborepo Nx / Turborepo 公式
GraphQL Apollo + Next.js + Codegen Apollo Client Docs
リアルタイムアプリ WebSocket + Socket.io + Liveblocks Liveblocks Next.js 統合
エッジコンピューティング エッジ関数 + Durable Objects Cloudflare Workers
プラットフォームエンジニアリング Backstage + 内部開発者ポータル Spotify Backstage

❓ よくある質問

Q Vercel とセルフホスト Docker のどちらを選ぶべきですか?
A Vercel は 90% のチームに適しています。ゼロ設定、グローバル CDN、自動 HTTPS、プレビューデプロイが利用できます。セルフホスト Docker は以下のシナリオでのみ必要です:コンプライアンス要件(データをオンプレミスに保持する必要がある)、内部システム(パブリックインターネットアクセスが不要)、ハイパースケール環境(カスタムインフラストラクチャが必要)。TaskFlow では、Vercel を主要ソリューション、Docker をバックアップとして推奨します。
Q GitHub Actions の Lighthouse CI の適切なしきい値スコアはどれくらいですか?
A パフォーマンス ≥ 90、アクセシビリティ ≥ 90、ベストプラクティス ≥ 90、SEO ≥ 90 を推奨します。プロジェクトに特別な要件がある場合(多数のサードパーティスクリプトがパフォーマンスを低下させるなど)、しきい値を 80 に下げることもできますが、その理由を説明し、修正計画を概説する TODO ノートを追加する必要があります。
Q PostHog と Sentry は機能が重複していますか?
A いいえ。PostHog はユーザー行動分析(ページビュー、ボタンクリック、コンバージョンファネル)に焦点を当て、Sentry はエラートラッキング(クラッシュスタック、パフォーマンススパン、リリース健全性)に焦点を当てています。両者は補完関係にあります:PostHog は「ユーザーが何をしたか」を伝え、Sentry は「なぜ問題が発生したか」を伝えます。
Q Vercel Postgres とセルフホスト PostgreSQL の違いは何ですか?
A Vercel Postgres はマネージドサービスで、自動バックアップ、自動スケーリング、低遅延 VPC ネットワーキング、従量課金モデルを提供します。セルフホスト PostgreSQL は完全な制御を提供しますが、運用保守(バックアップ、監視、アップグレード)が必要です。TaskFlow では、開発にローカル Postgres、Vercel へのデプロイに Vercel Postgres、Docker でのセルフホストにコンテナ化 Postgres を使用します。
Q Docker マルチステージビルドが 3 つのステージに分かれているのはなぜですか?
A ステージ 1(deps)はすべての依存関係をインストールし、ステージ 2(builder)は開発依存関係のみを使用してビルドし、ステージ 3(runner)は成果物とランタイム依存関係のみをコピーします。最終イメージは 1.2 GB から 358 MB に圧縮され、70% 削減されます。本番コンテナには TypeScript コンパイラ、テストツール、node_modules などの開発依存関係は含まれません。
Q スタンドアロンモード(output: 'standalone')の目的は何ですか?
A @latest/next のスタンドアロンモードは、ランタイムに必要な最小限のファイルセット(server.js.next サブディレクトリ)のみを出力し、node_modules の不要なパッケージを除外します。Docker マルチステージビルドと組み合わせることで、最終イメージには Next.js ランタイムのみが含まれ、サイズと攻撃対象領域が大幅に削減されます。

📖 まとめ

📝 練習問題

  1. 基本問題 (⭐): TaskFlow を Vercel にデプロイし(無料アカウント)、カスタムドメインを設定し(オプション)、/api/health が 200 ステータスコードを返すことを確認します。NEXT_PUBLIC_POSTHOG_KEY 環境変数を設定し、PostHog がページビューイベントを受信することを確認します。

  2. 応用問題 (⭐⭐): ローカルでセルフホスト Docker ソリューションをテストします — Docker イメージをビルドし、docker-compose(App + Nginx + PostgreSQL)を起動し、自己署名 SSL 証明書を設定し、データベースマイグレーションを実行し、HTTPS アクセスを検証します。docker-compose.ymlnginx.confDockerfile をプロジェクトリポジトリにコミットします。

  3. 発展問題 (⭐⭐⭐): TaskFlow の完全な機能監視を実装します:PostHog で 5 つのキーイベント(task_created / task_completed / user_signup / file_uploaded / project_created)を定義し、属性(所要時間、ブラウザ、地理的位置)を追加する。Sentry でアラートルールを設定する(エラー率が 5% を超えた場合に Slack 通知と PagerDuty アラートを送信)。GitHub Actions に Playwright E2E テストステップを追加する(デプロイ → E2E → Lighthouse を順次実行)。最後に README.md を提出する:デプロイアーキテクチャ図、監視ダッシュボードのスクリーンショット、Lighthouse レポート、CI/CD ステータスバッジを含める。

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%