Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

README.md

第8章: 公開と運用

学習目標

Webサイトを実際に公開し、運用する方法を学びます。

  • Vercelへのデプロイ
  • カスタムドメインの設定
  • 環境変数の管理
  • SEO対策
  • パフォーマンス最適化
  • アナリティクス設定

成果物: 公開Webサイト


0. なぜ「公開」が必要なのか?ローカルと本番の違い

0-1. 「デプロイ」とは何か?

デプロイ(Deploy) = 「展開する」「配備する」という意味で、作ったWebサイトを世界中からアクセスできる状態にすることです。

ローカル環境 vs 本番環境

ローカル環境(開発中)
┌──────────────────────────────────────┐
│ あなたのPC                            │
│ ├─ Next.js 開発サーバー起動           │
│ │  (npm run dev)                      │
│ ├─ localhost:3000 でアクセス          │
│ └─ あなただけが見られる               │
└──────────────────────────────────────┘
本番環境(デプロイ後)
┌──────────────────────────────────────┐
│ Vercelのサーバー(世界中に分散)      │
│ ├─ Next.js 本番ビルド                │
│ │  (npm run build && npm start)      │
│ ├─ https://yoursite.vercel.app       │
│ └─ 世界中の誰でもアクセス可能         │
└──────────────────────────────────────┘

なぜローカル環境だけではダメなのか?

  1. あなたのPCを常に起動しておく必要がある

    • 電源を切ったら誰もアクセスできない
    • 電気代がかかる
    • PCが壊れたらサイトも消える
  2. セキュリティリスク

    • 自宅のIPアドレスが公開される
    • 攻撃のターゲットになる可能性
  3. パフォーマンスの問題

    • 自宅のインターネット回線は遅い
    • 同時に多くの人がアクセスすると落ちる

0-2. インターネットの仕組み:あなたのサイトはどうやって届く?

URLからWebサイトが表示されるまで

ユーザーの操作
┌──────────────────────────────────────┐
│ 1. ブラウザに「example.com」と入力   │
│    ↓                                 │
│ 2. DNSサーバーに問い合わせ           │
│    「example.comのIPアドレスは?」    │
│    ↓                                 │
│ 3. DNS: 「192.0.2.1 です」           │
│    ↓                                 │
│ 4. そのIPアドレスにHTTPリクエスト     │
│    GET / HTTP/1.1                    │
│    ↓                                 │
│ 5. サーバーがHTMLを返す              │
│    ↓                                 │
│ 6. ブラウザがHTMLを描画              │
└──────────────────────────────────────┘

DNSとは?

DNS (Domain Name System) = 「インターネットの電話帳」

人間が覚えやすい名前 → コンピュータが理解できる番号
example.com          → 192.0.2.1

これがないと...
❌ https://192.0.2.1 を覚える必要がある
✅ https://example.com で覚えられる

実際の通信フロー

あなた (東京)
    ↓ HTTPSリクエスト
CDNエッジサーバー (東京)
    ↓ キャッシュなし?
オリジンサーバー (米国)
    ↓ HTMLを生成
CDNエッジサーバー (東京)
    ↓ キャッシュして返す
あなた (東京)
    → 次回から高速!

0-3. ホスティングサービスとは?

従来型ホスティング vs クラウドホスティング

従来型ホスティング(レンタルサーバー)
┌──────────────────────────────────────┐
│ 1台の物理サーバーを共有               │
│ ├─ 月額固定費(例: 500円/月)         │
│ ├─ 容量制限あり(例: 10GB)           │
│ ├─ アクセス制限あり                   │
│ └─ 手動でファイルアップロード         │
│    (FTPなど)                          │
└──────────────────────────────────────┘

クラウドホスティング(Vercel, Netlify等)
┌──────────────────────────────────────┐
│ 世界中のサーバーに自動分散            │
│ ├─ 従量課金(使った分だけ)           │
│ ├─ 自動スケーリング                   │
│ │  (アクセス増→自動で増強)            │
│ ├─ Git連携で自動デプロイ              │
│ └─ CDN標準装備                        │
└──────────────────────────────────────┘

CDN (Content Delivery Network) とは?

世界中にサーバーを配置して、ユーザーに一番近いサーバーからコンテンツを配信する仕組み:

CDNなし
┌──────────────────────────────────────┐
│ 日本のユーザー                        │
│    ↓ (地球半周分の距離)              │
│ アメリカのサーバー                    │
│    → 遅い(500ms以上)                │
└──────────────────────────────────────┘

CDNあり
┌──────────────────────────────────────┐
│ 日本のユーザー                        │
│    ↓ (近距離)                        │
│ 東京のCDNサーバー                     │
│    → 速い(50ms以下)                 │
└──────────────────────────────────────┘

0-4. なぜVercelなのか?

Vercelの特徴

Vercelは Next.js の開発元(Vercel社)が提供するホスティングサービスです。

Vercelが特別な理由
┌──────────────────────────────────────┐
│ 1. Next.jsに最適化                    │
│    → SSR, ISRが標準で動く             │
│                                      │
│ 2. ゼロコンフィグ                     │
│    → 設定不要で動く                   │
│                                      │
│ 3. Git連携                           │
│    → pushするだけでデプロイ           │
│                                      │
│ 4. プレビューデプロイ                 │
│    → ブランチごとにURL発行            │
│                                      │
│ 5. Edge Functions                    │
│    → 世界中で高速実行                 │
└──────────────────────────────────────┘

Vercel vs 他のサービス

機能 Vercel Netlify GitHub Pages
Next.js SSR ✅ 完全対応 ⚠️ 限定的 ❌ 非対応
自動デプロイ
無料枠 ✅ 充実 ✅ 充実 ✅ 無制限
カスタムドメイン
Edge Functions
適用サイト SSR/ISR 静的サイト/簡易SSR 静的サイトのみ

0-5. CI/CD とは?自動デプロイの仕組み

CI/CD = Continuous Integration / Continuous Deployment

従来の手動デプロイ
┌──────────────────────────────────────┐
│ 1. コードを書く                       │
│ 2. ローカルでテスト                   │
│ 3. ビルドコマンド実行                 │
│ 4. FTPでファイルアップロード          │
│ 5. サーバー再起動                     │
│ 6. 動作確認                          │
│                                      │
│ → 毎回30分かかる                     │
│ → 手順を忘れる                       │
│ → 本番環境で直接作業(危険)         │
└──────────────────────────────────────┘

CI/CDの自動デプロイ
┌──────────────────────────────────────┐
│ 1. コードを書く                       │
│ 2. git push                          │
│                                      │
│ → あとは全自動!                     │
│    ├─ 自動テスト実行                 │
│    ├─ 自動ビルド                     │
│    ├─ 自動デプロイ                   │
│    └─ プレビューURL発行              │
│                                      │
│ → 3分で完了                         │
└──────────────────────────────────────┘

Vercelの自動デプロイフロー

開発者の作業
┌──────────────────────────────────────┐
│ コード変更                            │
│    ↓                                 │
│ git add .                            │
│ git commit -m "機能追加"              │
│ git push origin main                 │
└──────────────────────────────────────┘
         ↓
Vercelの自動処理
┌──────────────────────────────────────┐
│ 1. GitHub Webhookで変更検知           │
│    ↓                                 │
│ 2. ソースコード取得                   │
│    ↓                                 │
│ 3. 依存関係インストール               │
│    npm install                       │
│    ↓                                 │
│ 4. ビルド実行                        │
│    npm run build                     │
│    ↓                                 │
│ 5. エラーチェック                     │
│    ・TypeScriptの型エラー             │
│    ・リントエラー                     │
│    ・ビルドエラー                     │
│    ↓                                 │
│ 6. CDNに配信                         │
│    世界中のエッジサーバーに展開       │
│    ↓                                 │
│ 7. デプロイ完了通知                   │
│    GitHub + Slackに通知              │
└──────────────────────────────────────┘

プレビューデプロイの威力

ブランチ戦略とプレビュー
┌──────────────────────────────────────┐
│ main ブランチ                         │
│ → https://yoursite.com                │
│ → 本番環境                            │
│                                      │
│ feature/new-page ブランチ             │
│ → https://yoursite-abc123.vercel.app │
│ → プレビュー環境                      │
│                                      │
│ bugfix/typo ブランチ                  │
│ → https://yoursite-def456.vercel.app │
│ → プレビュー環境                      │
└──────────────────────────────────────┘

利点:
✅ 本番に影響を与えずテスト可能
✅ チームメンバーと簡単に共有
✅ クライアントに見せられる
✅ マージ前に動作確認

0-6. 環境変数はなぜ重要?

環境変数とは?

アプリケーションの設定値を、コードの外で管理する仕組みです。

環境変数がない場合(❌ 危険)
┌──────────────────────────────────────┐
│ const API_KEY = "sk-1234567890";     │
│ // ↑ GitHubにpushされる               │
│ // → 全世界に公開される               │
│ // → APIキーが漏洩                    │
│ // → 不正利用される                   │
└──────────────────────────────────────┘

環境変数を使う場合(✅ 安全)
┌──────────────────────────────────────┐
│ const API_KEY = process.env.API_KEY; │
│ // ↑ 実際の値はサーバーに保存         │
│ // → GitHubにはコードのみ             │
│ // → 秘密情報は守られる               │
└──────────────────────────────────────┘

なぜ環境ごとに値を変える?

環境ごとの環境変数
┌──────────────────────────────────────┐
│ ローカル環境 (.env.local)             │
│ API_URL=http://localhost:8000/api    │
│ DEBUG_MODE=true                      │
│ STRIPE_KEY=test_key                  │
│                                      │
│ 本番環境 (Vercelの設定)               │
│ API_URL=https://api.yoursite.com     │
│ DEBUG_MODE=false                     │
│ STRIPE_KEY=live_key                  │
└──────────────────────────────────────┘

理由:
1. ローカルではテスト用API/DBを使う
2. 本番では本物のAPI/DBを使う
3. デバッグ情報は本番で非表示にする

NEXT_PUBLIC_ プレフィックスの意味

// ❌ ブラウザでは使えない(undefined)
const secret = process.env.DATABASE_URL;

// ✅ ブラウザでも使える
const publicKey = process.env.NEXT_PUBLIC_API_KEY;

なぜ区別が必要?

サーバーサイドのみの環境変数
┌──────────────────────────────────────┐
│ DATABASE_URL=postgres://...          │
│ API_SECRET_KEY=xxx                   │
│                                      │
│ → ブラウザに送信されない             │
│ → ユーザーに見られない               │
│ → 安全                               │
└──────────────────────────────────────┘

NEXT_PUBLIC_ 環境変数
┌──────────────────────────────────────┐
│ NEXT_PUBLIC_ANALYTICS_ID=GA-123      │
│ NEXT_PUBLIC_API_URL=https://...      │
│                                      │
│ → JavaScriptバンドルに埋め込まれる    │
│ → ブラウザで使える                   │
│ → ユーザーにも見られる               │
└──────────────────────────────────────┘

0-7. SEOとは?なぜ重要?

SEO = Search Engine Optimization(検索エンジン最適化)

Googleがあなたのサイトを見つける仕組み

検索エンジンの動作
┌──────────────────────────────────────┐
│ 1. クローリング (Crawling)            │
│    Googleのボットがサイトを巡回       │
│    ↓                                 │
│ 2. インデックス登録 (Indexing)        │
│    内容を分析してデータベースに保存   │
│    ↓                                 │
│ 3. ランキング (Ranking)               │
│    検索キーワードに対して順位決定     │
│    ↓                                 │
│ 4. 検索結果に表示                     │
│    ユーザーがクリック                 │
└──────────────────────────────────────┘

メタデータの重要性

検索結果に表示される情報:

<head>
  <!-- これがGoogleに読まれる -->
  <title>サイト名 | ホームページ</title>
  <meta name="description" content="サイトの説明文" />
  <meta property="og:image" content="/og-image.jpg" />
</head>

Google検索結果での表示:

┌──────────────────────────────────────┐
│ サイト名 | ホームページ               │  ← title
│ https://yoursite.com                 │  ← URL
│ サイトの説明文。初心者向けに...       │  ← description
└──────────────────────────────────────┘

SNSでシェアされたときの見た目(OGP)

Twitter/Facebook等でシェア
┌──────────────────────────────────────┐
│ ┌────────────────────────────────┐   │
│ │                                │   │
│ │     [OG画像が表示される]        │   │
│ │                                │   │
│ └────────────────────────────────┘   │
│ サイト名                              │
│ サイトの説明文                        │
│ yoursite.com                         │
└──────────────────────────────────────┘

0-8. パフォーマンスはなぜ重要?

パフォーマンスの影響

読み込み速度と離脱率の関係
┌──────────────────────────────────────┐
│ 1秒   → 離脱率  7%                   │
│ 3秒   → 離脱率 32%                   │
│ 5秒   → 離脱率 90%                   │
│ 10秒  → 離脱率 123%(ほぼ全員)      │
└──────────────────────────────────────┘

1秒遅くなるごとに:
- コンバージョン率 7% 低下
- ページビュー 11% 低下
- 顧客満足度 16% 低下

Core Web Vitals(コアウェブバイタル)

Googleが重視する3つの指標:

1. LCP (Largest Contentful Paint)
   → 最も大きいコンテンツが表示されるまでの時間
   ✅ 2.5秒以内が理想

2. FID (First Input Delay)
   → ユーザーの最初の操作に反応するまでの時間
   ✅ 100ms以内が理想

3. CLS (Cumulative Layout Shift)
   → 視覚的な安定性(レイアウトのズレ)
   ✅ 0.1以下が理想

なぜNext.jsの最適化機能を使うのか?

通常の画像読み込み
┌──────────────────────────────────────┐
│ <img src="huge-image.jpg" />         │
│                                      │
│ 問題:                                │
│ ❌ 5MB の画像をそのまま読み込む       │
│ ❌ すべての画像を最初に読み込む       │
│ ❌ どのデバイスでも同じサイズ         │
│                                      │
│ 結果: ページが重い、遅い              │
└──────────────────────────────────────┘

Next.js の Image コンポーネント
┌──────────────────────────────────────┐
│ <Image src="/image.jpg" ... />       │
│                                      │
│ 自動最適化:                          │
│ ✅ WebP/AVIF に自動変換               │
│ ✅ 遅延読み込み(Lazy Loading)       │
│ ✅ レスポンシブ(デバイス別サイズ)   │
│ ✅ CDNでキャッシュ                    │
│                                      │
│ 結果: 読み込み速度 3〜5倍改善         │
└──────────────────────────────────────┘

1. Vercelへのデプロイ

1-1. Vercelとは

Next.jsの開発元が提供する、最も簡単なホスティングサービスです。

特徴:

  • Next.jsに最適化
  • 無料プランあり
  • 自動デプロイ
  • カスタムドメイン対応
  • 世界中のCDN

1-2. デプロイ手順

ステップ1: GitHubにプッシュ

# Gitの初期化(まだの場合)
git init
git add .
git commit -m "Initial commit"

# GitHubリポジトリの作成後
git remote add origin https://github.com/username/repository.git
git push -u origin main

ステップ2: Vercelアカウント作成

  1. Vercelにアクセス
  2. 「Sign Up」からGitHubアカウントで登録

ステップ3: プロジェクトをインポート

  1. Vercelダッシュボードで「Add New...」→「Project」
  2. GitHubリポジトリを選択
  3. 「Import」をクリック

ステップ4: デプロイ設定

Framework Preset: Next.js
Build Command: npm run build
Output Directory: .next
Install Command: npm install

ステップ5: デプロイ

「Deploy」ボタンをクリック → 数分で公開完了!

📸 スクリーンショット: Vercelのデプロイ画面


2. 環境変数の管理

2-1. ローカル環境

.env.local ファイルを作成:

# .env.local
NEXT_PUBLIC_API_KEY=your_api_key_here
DATABASE_URL=postgres://...

注意:

  • NEXT_PUBLIC_ プレフィックス = ブラウザで使える
  • プレフィックスなし = サーバーのみで使える
  • .env.local.gitignore に追加

2-2. Vercelでの環境変数設定

  1. Vercelダッシュボード → プロジェクト → Settings
  2. Environment Variables タブ
  3. 環境変数を追加
  4. 「Save」→ 再デプロイ

2-3. 環境変数の使用

// サーバーコンポーネント
const apiKey = process.env.API_KEY;

// クライアントコンポーネント
const publicKey = process.env.NEXT_PUBLIC_API_KEY;

3. カスタムドメインの設定

3-1. ドメインの取得

おすすめのドメインレジストラ:

3-2. Vercelでドメインを設定

  1. Vercelダッシュボード → プロジェクト → Settings
  2. Domains タブ
  3. ドメイン名を入力(例: example.com
  4. DNSレコードを設定(指示通りに設定)

DNSレコード例:

Type: A
Name: @
Value: 76.76.21.21

Type: CNAME
Name: www
Value: cname.vercel-dns.com

4. SEO対策

4-1. メタデータの最適化

// app/layout.tsx
export const metadata = {
  title: {
    default: 'サイト名',
    template: '%s | サイト名'
  },
  description: 'サイトの説明文',
  keywords: ['Next.js', 'React', 'TypeScript'],
  authors: [{ name: 'あなたの名前' }],
  openGraph: {
    title: 'サイト名',
    description: 'サイトの説明文',
    url: 'https://example.com',
    siteName: 'サイト名',
    images: [
      {
        url: 'https://example.com/og-image.jpg',
        width: 1200,
        height: 630,
      }
    ],
    locale: 'ja_JP',
    type: 'website',
  },
  twitter: {
    card: 'summary_large_image',
    title: 'サイト名',
    description: 'サイトの説明文',
    images: ['https://example.com/twitter-image.jpg'],
  },
};

4-2. sitemap.xml の生成

// app/sitemap.ts
import { MetadataRoute } from 'next';

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: 'https://example.com',
      lastModified: new Date(),
      changeFrequency: 'yearly',
      priority: 1,
    },
    {
      url: 'https://example.com/about',
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 0.8,
    },
    {
      url: 'https://example.com/blog',
      lastModified: new Date(),
      changeFrequency: 'weekly',
      priority: 0.5,
    },
  ];
}

4-3. robots.txt の設定

// app/robots.ts
import { MetadataRoute } from 'next';

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: '*',
      allow: '/',
      disallow: '/private/',
    },
    sitemap: 'https://example.com/sitemap.xml',
  };
}

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

5-1. 画像最適化

import Image from 'next/image';

<Image
  src="/hero.jpg"
  alt="ヒーロー画像"
  width={1200}
  height={600}
  priority // LCP対策
  quality={85} // 品質調整
/>

5-2. フォントの最適化

// app/layout.tsx
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'] });

export default function RootLayout({ children }) {
  return (
    <html lang="ja" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

5-3. 動的インポート

import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'), {
  loading: () => <p>読み込み中...</p>,
  ssr: false // クライアントのみでレンダリング
});

6. アナリティクス

6-1. Google Analyticsの設定

// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html lang="ja">
      <head>
        <Script
          src={`https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX`}
          strategy="afterInteractive"
        />
        <Script id="google-analytics" strategy="afterInteractive">
          {`
            window.dataLayer = window.dataLayer || [];
            function gtag(){dataLayer.push(arguments);}
            gtag('js', new Date());
            gtag('config', 'G-XXXXXXXXXX');
          `}
        </Script>
      </head>
      <body>{children}</body>
    </html>
  );
}

6-2. Vercel Analytics

npm install @vercel/analytics
// app/layout.tsx
import { Analytics } from '@vercel/analytics/react';

export default function RootLayout({ children }) {
  return (
    <html lang="ja">
      <body>
        {children}
        <Analytics />
      </body>
    </html>
  );
}

7. 継続的デプロイ(CI/CD)

7-1. 自動デプロイの仕組み

Vercelは自動的に以下を実行します:

  1. GitHubにプッシュ
  2. Vercelが検知
  3. ビルド実行
  4. デプロイ
  5. プレビューURL発行

7-2. プレビューデプロイ

  • main ブランチ → 本番環境
  • それ以外のブランチ → プレビュー環境
git checkout -b feature/new-page
git add .
git commit -m "Add new page"
git push origin feature/new-page
# → プレビューURLが自動生成される

ミニ課題

課題1: ポートフォリオサイトをデプロイ

これまで作成したポートフォリオサイトをVercelにデプロイしてください。

課題2: SEO対策を実施

以下を追加してください:

  • Open Graphメタタグ
  • sitemap.xml
  • robots.txt

課題3: パフォーマンスチェック

PageSpeed Insightsでスコアを確認し、改善してください。


よくあるエラーと解決策

エラー1: Build failed

原因: TypeScriptエラーやビルドエラー

解決策:

# ローカルでビルド確認
npm run build

エラー2: 環境変数が読み込まれない

原因: Vercelに環境変数を設定していない

解決策: Vercelダッシュボードで環境変数を設定後、再デプロイ

エラー3: ドメインが反映されない

原因: DNS設定の反映待ち

解決策: 最大48時間待つ(通常は数時間)


まとめ

この章では以下のことを学びました:

  • ✅ Vercelへのデプロイ方法
  • ✅ 環境変数の管理
  • ✅ カスタムドメインの設定
  • ✅ SEO対策
  • ✅ パフォーマンス最適化
  • ✅ アナリティクスの設定

次の章では、応用的なテーマに取り組みます。

この章で習得すべきスキル

学習を完了したら、以下の項目をチェックしてください:

基礎知識の理解

  • デプロイの意味を理解している
  • ローカル環境と本番環境の違いを理解している
  • DNSの仕組みを理解している
  • CDNの役割と利点を理解している
  • CI/CDの概念を理解している

Vercel デプロイ

  • Vercelアカウントを作成できる
  • GitHubリポジトリと連携できる
  • プロジェクトをインポートできる
  • 自動デプロイの仕組みを理解している
  • プレビューデプロイを活用できる

環境変数

  • .env.localファイルを作成できる
  • NEXT_PUBLIC_プレフィックスの意味を理解している
  • Vercelで環境変数を設定できる
  • 秘密情報を適切に管理できる

ドメイン設定

  • カスタムドメインの設定方法を理解している
  • DNSレコードの設定ができる

SEO対策

  • metadataオブジェクトを設定できる
  • titleとdescriptionを最適化できる
  • Open Graphタグを設定できる
  • sitemap.xmlを生成できる
  • robots.txtを設定できる

パフォーマンス最適化

  • next/imageで画像を最適化できる
  • next/fontでフォントを最適化できる
  • dynamic importでコード分割できる
  • Core Web Vitalsの概念を理解している

アナリティクス

  • Google Analyticsを設定できる
  • Vercel Analyticsを有効化できる

トラブルシューティング

  • ビルドエラーを解決できる
  • 環境変数の問題を解決できる
  • PageSpeed Insightsでパフォーマンスを確認できる

実践スキル

  • 自分のWebサイトを公開できる
  • GitHubにコードをpushできる
  • デプロイの状況を確認できる
  • 本番URLにアクセスして動作確認できる

次のステップへの準備

  • 継続的な改善の重要性を理解している
  • ユーザーフィードバックの収集方法を理解している

参考リンク