CI/CD パイプラインのベスト プラクティス: 信頼性の高いデプロイメントへの方法を自動化する

実稼働ワークフローでのテスト、ステージング、デプロイの自動化、ロールバック戦略、セキュリティ スキャンのベスト プラクティスを使用して、信頼性の高い CI/CD パイプラインを構築します。

E
ECOSIRE Research and Development Team
|2026年3月16日4 分で読める827 語数|

CI/CD パイプラインのベスト プラクティス: 信頼性の高いデプロイメントへの方法を自動化する

成熟した CI/CD パイプラインを備えたチームは、そうでないチームに比べて 208 倍の頻度でデプロイしますが、変更失敗率は 7 倍低くなります。 脆弱な「ほとんど機能する」パイプラインと、厳しいテストを経たデプロイメント システムとの違いは、アマチュアの自動化と運用レベルのインフラストラクチャを区別するいくつかの実践方法に帰着します。

このガイドでは、CI/CD パイプラインを大規模に信頼できるものにするための具体的な実践、構成、アーキテクチャ上の決定について説明します。

重要なポイント

  • パイプラインの実行時間は開発者の生産性に直接影響します --- スイート全体の目標は 10 分未満です
  • CI のセキュリティ スキャンは、本番環境に到達する前に脆弱性の 85% を検出します。
  • 自動ロールバック メカニズムにより、平均復旧時間が数時間から数分に短縮されます。
  • ブランチ保護ルールと必要なステータスチェックにより、壊れたコードがメインに到達するのを防ぎます

パイプラインのアーキテクチャ

5 段階モデル

すべての運用 CI/CD パイプラインでは、次の 5 つのステージを実装する必要があります。

ステージ 1: Lint と検証 (目標: <2 分)

lint:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 20
        cache: pnpm
    - run: pnpm install --frozen-lockfile
    - run: pnpm lint
    - run: pnpm typecheck

ステージ 2: テスト (目標: 8 分未満)

test:
  runs-on: ubuntu-latest
  services:
    postgres:
      image: postgres:17
      env:
        POSTGRES_PASSWORD: test
        POSTGRES_DB: test
      ports:
        - 5432:5432
      options: >-
        --health-cmd pg_isready
        --health-interval 10s
        --health-timeout 5s
        --health-retries 5
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
      with:
        node-version: 20
        cache: pnpm
    - run: pnpm install --frozen-lockfile
    - run: pnpm test
      env:
        DATABASE_URL: postgresql://postgres:test@localhost:5432/test

ステージ 3: ビルド (目標: 5 分未満)

Docker イメージを構築し、アセットをコンパイルし、実稼働バンドルを生成します。依存関係を積極的にキャッシュします。

ステージ 4: ステージングへのデプロイ

メインへのマージ時に自動デプロイメント。ステージング環境に対してスモーク テストを実行します。

ステージ 5: 本番環境への展開

手動の承認ゲート、またはステージング検証に合格した後に自動化されます。


速度の最適化

パイプラインが遅いと、開発者の生産性が低下します。チーム全体で CI 待機時間が 1 分ごとに増えると、コンテキスト切り替えにかかる時間の損失が何時間も発生します。

並列化

独立したジョブを同時に実行します。

jobs:
  lint:
    runs-on: ubuntu-latest
    steps: [...]

  test-unit:
    runs-on: ubuntu-latest
    steps: [...]

  test-integration:
    runs-on: ubuntu-latest
    steps: [...]

  test-e2e:
    runs-on: ubuntu-latest
    steps: [...]

  build:
    needs: [lint, test-unit, test-integration, test-e2e]
    runs-on: ubuntu-latest
    steps: [...]

依存関係のキャッシュ

- uses: actions/cache@v4
  with:
    path: |
      ~/.pnpm-store
      node_modules
      apps/*/node_modules
      packages/*/node_modules
    key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
    restore-keys: |
      ${{ runner.os }}-pnpm-

Docker レイヤーのキャッシュ

- uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: registry.example.com/app:${{ github.sha }}
    cache-from: type=gha
    cache-to: type=gha,mode=max

パイプライン速度のベンチマーク

最適化改善
キャッシュなし12分---ベースライン
依存関係のキャッシュ12分7分42%
Docker 層のキャッシュ7分4.5分36%
並列テストスイート4.5分3分33%
ターボリモートキャッシュ3分2分33%

セキュリティスキャン

依存関係の脆弱性スキャン

security:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4

    - name: Run Snyk to check for vulnerabilities
      uses: snyk/actions/node@master
      env:
        SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
      with:
        args: --severity-threshold=high

    - name: Run Trivy vulnerability scanner
      uses: aquasecurity/trivy-action@master
      with:
        scan-type: fs
        scan-ref: .
        severity: CRITICAL,HIGH
        exit-code: 1

秘密スキャン

    - name: Detect secrets
      uses: trufflesecurity/trufflehog@main
      with:
        extra_args: --only-verified

SAST (静的アプリケーション セキュリティ テスト)

    - name: CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        languages: javascript-typescript

セキュリティゲートポリシー

重大度の確認PR行動生産動作
クリティカルブロックマージデプロイメントをブロックする
ブロックマージデプロイメントをブロックする
警告、マージを許可します警告、展開を許可します
低い情報提供のみ情報提供のみ

ブランチ保護とマージ戦略

必要なステータスチェック

メイン ブランチで必要なステータス チェックとしてこれらを設定します。

  1. lint と typecheck に合格する必要がある
  2. すべての単体テストに合格する必要がある
  3. すべての統合テストに合格する必要があります
  4. セキュリティ スキャンには重大/高レベルの検出結果があってはなりません
  5. ビルドは成功する必要があります

マージ戦略

機能ブランチにスカッシュ マージを使用して、クリーンな履歴を維持します。

main: A --- B --- C --- D (each is a squashed feature)

PR には少なくとも 1 つの承認が必要です。クリティカル パス (認証、請求、データベース移行) の場合は、2 つの承認が必要です。


導入戦略

ブルーグリーン展開

2 つの同一の実稼働環境を維持します。一方にトラフィックをルーティングしながら、もう一方に展開します。

#!/bin/bash
# blue-green-deploy.sh

CURRENT=$(kubectl get service production -o jsonpath='{.spec.selector.version}')

if [ "$CURRENT" == "blue" ]; then
  TARGET="green"
else
  TARGET="blue"
fi

echo "Current: $CURRENT, deploying to: $TARGET"

# Deploy to inactive environment
kubectl set image deployment/$TARGET-app app=registry.example.com/app:$TAG

# Wait for rollout
kubectl rollout status deployment/$TARGET-app --timeout=300s

# Run smoke tests against target
curl -sf "http://$TARGET.internal/health" || exit 1

# Switch traffic
kubectl patch service production -p "{\"spec\":{\"selector\":{\"version\":\"$TARGET\"}}}"

echo "Traffic switched to $TARGET"

ローリング展開

ポッドを段階的に更新します。

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 25%
    maxUnavailable: 0

maxUnavailable: 0 により、展開中に容量が失われないことが保証されます。

カナリアのデプロイメント

トラフィックのごく一部を新しいバージョンにルーティングします。

# Using Istio for traffic splitting
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: app-canary
spec:
  hosts:
    - app.example.com
  http:
    - route:
        - destination:
            host: app-stable
          weight: 95
        - destination:
            host: app-canary
          weight: 5

展開戦略の詳細については、[ゼロダウンタイム展開] (/blog/zero-downtime-deployments) に関する専用ガイドを参照してください。


ロールバックの自動化

ヘルスチェック失敗時の自動ロールバック

deploy-production:
  runs-on: ubuntu-latest
  steps:
    - name: Deploy
      run: |
        kubectl set image deployment/app app=${{ env.IMAGE }}
        kubectl rollout status deployment/app --timeout=300s

    - name: Smoke tests
      run: |
        sleep 30
        STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://app.example.com/health)
        if [ "$STATUS" != "200" ]; then
          echo "Health check failed with status $STATUS"
          kubectl rollout undo deployment/app
          exit 1
        fi

    - name: Monitor error rate
      run: |
        # Check error rate over 5 minutes
        ERROR_RATE=$(curl -s "http://prometheus:9090/api/v1/query?query=rate(http_requests_total{status=~'5..'}[5m])/rate(http_requests_total[5m])" | jq '.data.result[0].value[1]' -r)
        if (( $(echo "$ERROR_RATE > 0.01" | bc -l) )); then
          echo "Error rate $ERROR_RATE exceeds threshold"
          kubectl rollout undo deployment/app
          exit 1
        fi

モノリポジトリのパイプラインの最適化

Monorepo プロジェクト (Turborepo を使用するプロジェクトなど) の場合は、変更された部分のみを実行します。

- name: Determine affected packages
  id: affected
  run: |
    AFFECTED=$(npx turbo run build --filter='...[HEAD~1]' --dry-run=json | jq -r '.packages[]')
    echo "packages=$AFFECTED" >> $GITHUB_OUTPUT

- name: Test affected packages
  if: steps.affected.outputs.packages != ''
  run: npx turbo run test --filter='...[HEAD~1]'

これにより、大規模なモノリポジトリ内の 1 つのパッケージにのみ影響する変更の CI 時間が 60 ~ 80% 短縮されます。


よくある質問

どれくらいの頻度で実稼働環境にデプロイする必要がありますか?

パイプラインが許す限り頻繁にデプロイします。パフォーマンスの高いチームは、1 日に複数回デプロイします。目標は、レビュー、テスト、ロールバックが簡単な、小規模で段階的な変更です。デプロイにリスクを感じる場合、それは、デプロイの数を減らすのではなく、パイプラインの自動テストとより優れたロールバック メカニズムが必要であることを示しています。

トランクベースの開発または機能ブランチを使用する必要がありますか?

ほとんどのチームでは、有効期間が短い (1 ~ 3 日) 機能ブランチが最適に機能します。トランクベースの開発には、より成熟したテスト インフラストラクチャと機能フラグが必要です。重要なことは、ブランチの存続期間が短いということです。存続期間の長い機能ブランチはマージの競合を引き起こし、フィードバックを遅らせます。

CI/CD でのデータベース移行はどのように処理すればよいですか?

アプリケーションをデプロイする前に、別のパイプライン ステップとして移行を実行します。移行に下位互換性があることを確認します (古いアプリケーション バージョンが新しいスキーマで動作する必要があります)。展開と縮小のパターンを使用します。最初に新しい列を追加し、古い列と新しい列の両方に書き込むコードをデプロイし、データを移行してから、後続のリリースで古い列を削除します。

CI に適したテスト ピラミッドは何ですか?

一般的な Web アプリケーションの場合: 70% 単体テスト (高速、分離)、20% 統合テスト (API エンドポイント、データベース クエリ)、10% E2E テスト (重要なユーザー フロー)。単体テストはコミットごとに実行されます。統合テストは PR で実行されます。 E2E テストは、メインへのマージ時、または実稼働デプロイの前に実行されます。


次に何が起こるか

適切に設計された CI/CD パイプラインは、他のすべての DevOps 実践の基盤です。信頼性の高い自動化が導入されていれば、コードとしてのインフラストラクチャ運用監視負荷テスト を自信を持って追求できます。

CI/CD パイプラインの設計と実装については ECOSIRE にお問い合わせ、完全なインフラストラクチャ ロードマップについては 中小企業向けの DevOps ガイド を参照してください。


ECOSIRE が発行 -- 企業が自信を持ってソフトウェアを導入できるように支援します。

E

執筆者

ECOSIRE Research and Development Team

ECOSIREでエンタープライズグレードのデジタル製品を開発。Odoo統合、eコマース自動化、AI搭載ビジネスソリューションに関するインサイトを共有しています。

WhatsAppでチャット