CI/CD設定とは?初心者でも分かる自動化パイプラインの作り方完全ガイド

プログラミング・IT

ソフトウェア開発の現場で「CI/CD」という言葉を耳にしたことはありませんか?

「何やら便利そうだけど、難しそう…」「設定方法が分からない」と感じている方も多いはずです。

実は、CI/CDは開発作業を自動化して、効率と品質を劇的に向上させる現代のソフトウェア開発には欠かせない仕組みなんです。手作業でのテストやデプロイから解放されて、本当に重要な開発作業に集中できるようになりますよ。

この記事では、CI/CDの基礎知識から実際の設定方法まで、プログラミング初心者の方にも分かりやすく解説していきます。

具体的な設定例をたくさん見ながら、あなたのプロジェクトにもCI/CDを導入してみましょう!


スポンサーリンク
  1. CI/CDとは?その基本を理解しよう
    1. CI/CDの正体
    2. なぜCI/CDが必要なの?
    3. CI/CDのメリット
  2. CIとCDの違いを詳しく見てみよう
    1. CI(継続的インテグレーション)とは
    2. CD(継続的デリバリー)とは
    3. CD(継続的デプロイメント)とは
    4. DeliveryとDeploymentの違い
  3. 主要なCI/CDツールを知ろう
    1. GitHub Actions
    2. GitLab CI/CD
    3. Jenkins
    4. CircleCI
    5. その他の選択肢
  4. CI/CD設定の基本要素
    1. 1. トリガー(Trigger)
    2. 2. ジョブ(Job)
    3. 3. ステップ(Step)
    4. 4. 環境(Environment)
    5. 5. アーティファクト(Artifact)
  5. GitHub Actionsの設定例
    1. 基本的なワークフロー
    2. Pythonプロジェクトの例
    3. デプロイを含む完全な例
  6. GitLab CI/CDの設定例
    1. 基本的な.gitlab-ci.yml
    2. Dockerを使った例
    3. 複数環境へのデプロイ
  7. CI/CD設定のベストプラクティス
    1. 1. 小さく頻繁にコミット
    2. 2. テストを徹底する
    3. 3. 高速化を意識する
    4. 4. 環境変数と秘密情報の管理
    5. 5. 失敗時の通知設定
    6. 6. ブランチ戦略を決める
  8. よくある問題と解決策
    1. 問題1:テストが遅すぎる
    2. 問題2:本番環境で動かない
    3. 問題3:デプロイが頻繁に失敗する
    4. 問題4:セキュリティの問題
    5. 問題5:コストが高い
  9. セキュリティを考慮したCI/CD
    1. 依存関係のスキャン
    2. コード品質チェック
    3. シークレットスキャン
  10. 実践例:実際のプロジェクトでの設定
    1. フルスタックWebアプリケーション
    2. モバイルアプリのビルド
  11. モニタリングとメトリクス
    1. パイプラインのメトリクス測定
    2. 通知とアラート
  12. まとめ

CI/CDとは?その基本を理解しよう

CI/CDの正体

CI/CDは、2つの重要な概念を組み合わせた言葉です。

  • CI:Continuous Integration(継続的インテグレーション)
  • CD:Continuous Delivery/Deployment(継続的デリバリー/デプロイメント)

簡単に言えば、コードの変更から本番環境への反映まで、すべてを自動化する仕組みのことなんです。

なぜCI/CDが必要なの?

従来の開発では、こんな問題がありました:

手作業の課題:

  • テストを実行し忘れる
  • デプロイ手順を間違える
  • 環境によって動作が違う
  • リリースに時間がかかる
  • 人為的ミスが発生しやすい

CI/CDを導入すると、これらの問題を解決できるんです。

CI/CDのメリット

開発スピードの向上
自動化により、リリースサイクルが短くなります。

品質の向上
自動テストで問題を早期発見できます。

人為的ミスの削減
手作業が減るので、ミスも減少します。

開発者の負担軽減
単純作業から解放されて、創造的な仕事に集中できます。

迅速なフィードバック
問題があればすぐに通知されるので、早く対応できます。


CIとCDの違いを詳しく見てみよう

CI(継続的インテグレーション)とは

CIは、コードの変更を頻繁に統合してテストする仕組みです。

具体的な流れ:

  1. 開発者がコードを変更
  2. Gitにプッシュ(アップロード)
  3. 自動的にビルドが実行される
  4. 自動テストが走る
  5. 結果が通知される

この一連の流れが、コードを変更するたびに自動実行されるんです。

CIの目的:

  • バグの早期発見
  • コードの品質維持
  • チーム開発での統合問題の防止

CD(継続的デリバリー)とは

Continuous Delivery(継続的デリバリー)は、いつでも本番環境にリリースできる状態を保つ仕組みです。

流れ:

  1. CIが成功
  2. ステージング環境にデプロイ
  3. 追加のテスト実行
  4. 手動承認を待つ
  5. 本番環境へデプロイ

最後のステップは人間が手動で承認します。安全性を重視する場合に適していますね。

CD(継続的デプロイメント)とは

Continuous Deployment(継続的デプロイメント)は、すべてを完全自動化した仕組みです。

流れ:

  1. CIが成功
  2. 自動的にステージング環境にデプロイ
  3. 自動テスト実行
  4. すべて成功したら自動的に本番環境にデプロイ

人間の承認なしで、コードの変更が数分で本番環境に反映されます。

DeliveryとDeploymentの違い

Continuous Delivery:

  • 最終的な本番デプロイは手動
  • より慎重なアプローチ
  • 金融系など厳格な業界に向いている

Continuous Deployment:

  • すべて完全自動
  • 超高速リリースサイクル
  • Web系サービスなどに向いている

どちらを選ぶかは、プロジェクトの性質次第ですよ。


主要なCI/CDツールを知ろう

GitHub Actions

GitHub Actionsは、GitHubに統合されたCI/CDサービスです。

特徴:

  • GitHubと完全統合
  • 設定ファイルはYAML形式
  • 豊富なマーケットプレイス
  • プライベートリポジトリでも月2,000分無料

向いているプロジェクト:

  • GitHubでホストしているプロジェクト
  • 小〜中規模のチーム
  • オープンソースプロジェクト

GitLab CI/CD

GitLab CI/CDは、GitLabに組み込まれたCI/CDツールです。

特徴:

  • GitLabに完全統合
  • 強力なパイプライン機能
  • 自社サーバーでも運用可能
  • Dockerとの相性が良い

向いているプロジェクト:

  • GitLabを使っているチーム
  • セルフホストしたい企業
  • 複雑なワークフローが必要な場合

Jenkins

Jenkinsは、老舗のCI/CDツールです。

特徴:

  • オープンソースで完全無料
  • 豊富なプラグイン(1,800以上)
  • 高いカスタマイズ性
  • 自社サーバーで運用

向いているプロジェクト:

  • 完全なカスタマイズが必要
  • 既存のインフラがある大企業
  • 複雑な要件がある場合

CircleCI

CircleCIは、高速実行に定評があるCI/CDサービスです。

特徴:

  • 実行速度が速い
  • Docker対応が優秀
  • 並列実行に強い
  • 無料プランあり

向いているプロジェクト:

  • ビルド時間を短縮したい
  • Dockerを使っている
  • 高速な開発サイクルが必要

その他の選択肢

Travis CI: オープンソース向け
Azure Pipelines: Microsoft系開発
Bitbucket Pipelines: Bitbucketユーザー向け
AWS CodePipeline: AWSエコシステム内

どれを選ぶかは、使っているGitホスティングサービスや要件次第ですね。


CI/CD設定の基本要素

1. トリガー(Trigger)

トリガーは、パイプラインを起動する条件のことです。

主なトリガー:

  • プッシュトリガー:コードがプッシュされたとき
  • プルリクエストトリガー:PRが作成されたとき
  • スケジュールトリガー:定期実行(毎日0時など)
  • 手動トリガー:ボタンクリックで実行

プロジェクトに応じて、適切なトリガーを設定します。

2. ジョブ(Job)

ジョブは、実行される作業の単位です。

典型的なジョブ:

  • ビルド(Build)
  • テスト(Test)
  • リンター(Lint)
  • セキュリティスキャン
  • デプロイ(Deploy)

複数のジョブを並列実行することもできますよ。

3. ステップ(Step)

ステップは、ジョブを構成する個々のタスクです。

例:テストジョブのステップ

  1. コードをチェックアウト
  2. 依存関係をインストール
  3. データベースをセットアップ
  4. テストを実行
  5. カバレッジレポートを生成

ステップは順番に実行されます。

4. 環境(Environment)

環境は、コードが実行される場所です。

主な環境:

  • 開発環境(Development):開発中のコード
  • ステージング環境(Staging):本番に近いテスト環境
  • 本番環境(Production):実際のユーザーが使う環境

段階的にデプロイすることで、リスクを軽減できます。

5. アーティファクト(Artifact)

アーティファクトは、ビルド成果物のことです。

例:

  • コンパイル済みバイナリ
  • Dockerイメージ
  • デプロイパッケージ
  • テストレポート

これらを保存しておくと、後で利用できて便利なんです。


GitHub Actionsの設定例

基本的なワークフロー

GitHub Actionsでは、.github/workflows/ ディレクトリにYAMLファイルを置きます。

シンプルなNode.jsプロジェクトの例:

name: CI

# トリガーの設定
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

# ジョブの定義
jobs:
  test:
    # 実行環境
    runs-on: ubuntu-latest

    # ステップの定義
    steps:
    # 1. コードをチェックアウト
    - uses: actions/checkout@v3

    # 2. Node.jsをセットアップ
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'

    # 3. 依存関係をインストール
    - name: Install dependencies
      run: npm ci

    # 4. テストを実行
    - name: Run tests
      run: npm test

    # 5. ビルドを実行
    - name: Build
      run: npm run build

この設定で、プッシュやPRのたびに自動的にテストが実行されます。

Pythonプロジェクトの例

複数バージョンでのテスト:

name: Python CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.9', '3.10', '3.11']

    steps:
    - uses: actions/checkout@v3

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
        pip install pytest pytest-cov

    - name: Run tests
      run: |
        pytest --cov=./ --cov-report=xml

    - name: Upload coverage
      uses: codecov/codecov-action@v3
      with:
        file: ./coverage.xml

Python 3.9、3.10、3.11の3つのバージョンで並列テストが実行されます。

デプロイを含む完全な例

テスト→ビルド→デプロイのフロー:

name: CI/CD Pipeline

on:
  push:
    branches: [ main ]

jobs:
  # テストジョブ
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'

    - name: Install and test
      run: |
        npm ci
        npm test

  # ビルドジョブ(テスト成功後に実行)
  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3

    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'

    - name: Build
      run: |
        npm ci
        npm run build

    - name: Upload artifact
      uses: actions/upload-artifact@v3
      with:
        name: dist
        path: dist/

  # デプロイジョブ(ビルド成功後に実行)
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
    - name: Download artifact
      uses: actions/download-artifact@v3
      with:
        name: dist

    - name: Deploy to production
      run: |
        # ここにデプロイコマンド
        echo "Deploying to production..."

needs キーワードで、ジョブの実行順序を制御できます。


GitLab CI/CDの設定例

基本的な.gitlab-ci.yml

GitLab CI/CDでは、ルートディレクトリに .gitlab-ci.yml ファイルを置きます。

シンプルな例:

# ステージの定義
stages:
  - test
  - build
  - deploy

# テストジョブ
test:
  stage: test
  image: node:18
  script:
    - npm ci
    - npm test
  only:
    - main
    - develop

# ビルドジョブ
build:
  stage: build
  image: node:18
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 week
  only:
    - main

# デプロイジョブ
deploy_production:
  stage: deploy
  script:
    - echo "Deploying to production"
    - ./deploy.sh
  environment:
    name: production
    url: https://example.com
  only:
    - main
  when: manual  # 手動承認が必要

Dockerを使った例

コンテナベースのビルド:

stages:
  - build
  - test
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

# Dockerイメージをビルド
build_image:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG

# イメージをテスト
test_image:
  stage: test
  image: $IMAGE_TAG
  script:
    - npm test

# 本番環境にデプロイ
deploy_production:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache curl
  script:
    - curl -X POST $WEBHOOK_URL -d "image=$IMAGE_TAG"
  only:
    - main
  when: manual

複数環境へのデプロイ

ステージングと本番の分離:

stages:
  - test
  - deploy_staging
  - deploy_production

test:
  stage: test
  script:
    - npm ci
    - npm test

# ステージング環境へ自動デプロイ
deploy_staging:
  stage: deploy_staging
  script:
    - ./deploy.sh staging
  environment:
    name: staging
    url: https://staging.example.com
  only:
    - develop

# 本番環境へ手動デプロイ
deploy_production:
  stage: deploy_production
  script:
    - ./deploy.sh production
  environment:
    name: production
    url: https://example.com
  only:
    - main
  when: manual

ステージングは自動、本番は手動承認という安全な構成ですね。


CI/CD設定のベストプラクティス

1. 小さく頻繁にコミット

良い習慣:

  • 毎日複数回コミットする
  • 機能ごとに分けてコミット
  • 変更を小さく保つ

小さな変更なら、問題があってもすぐに原因を特定できます。

2. テストを徹底する

重要なテスト:

  • ユニットテスト:個々の関数をテスト
  • 統合テスト:複数モジュールの連携をテスト
  • E2Eテスト:実際のユーザー操作をシミュレート
  • セキュリティテスト:脆弱性スキャン

テストカバレッジは最低でも80%を目指しましょう。

3. 高速化を意識する

パイプラインを速くする工夫:

キャッシュの活用:

- name: Cache dependencies
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

並列実行:
複数のジョブを同時実行して時間短縮

必要なテストだけ実行:
変更されたファイルに関連するテストのみ実行

遅いパイプラインは開発者のストレスになるので、スピードは重要です。

4. 環境変数と秘密情報の管理

絶対にやってはいけないこと:

  • パスワードをコードに直接書く
  • APIキーをGitにコミットする

正しい方法:

# GitHub Actionsの例
- name: Deploy
  env:
    API_KEY: ${{ secrets.API_KEY }}
    DATABASE_URL: ${{ secrets.DATABASE_URL }}
  run: ./deploy.sh

秘密情報は必ずCI/CDツールのシークレット管理機能を使いましょう。

5. 失敗時の通知設定

通知先の例:

  • Slackチャンネル
  • メール
  • Discord
  • Microsoft Teams

パイプラインが失敗したら、すぐに気づけるようにしておくことが大切です。

6. ブランチ戦略を決める

Git Flowの例:

  • main:本番環境用
  • develop:開発用
  • feature/:機能開発用

それぞれのブランチに適したCI/CD設定をしましょう。


よくある問題と解決策

問題1:テストが遅すぎる

症状:
パイプラインの実行に30分以上かかる

解決策:

並列実行を活用:

test:
  strategy:
    matrix:
      shard: [1, 2, 3, 4]
  steps:
    - run: npm test -- --shard=${{ matrix.shard }}/4

キャッシュを使う:
依存関係のインストール時間を短縮

不要なテストを削除:
重複したテストや意味のないテストを整理

問題2:本番環境で動かない

症状:
CIは成功するのに、デプロイ後にエラー

原因と解決策:

環境変数の違い:
→ ステージング環境で本番に近い設定をテスト

依存関係のバージョン:
→ ロックファイルを使って固定

環境依存のコード:
→ 環境差異を吸収する設定を追加

問題3:デプロイが頻繁に失敗する

症状:
デプロイの成功率が低い

解決策:

ロールバック機能の実装:

deploy:
  script:
    - ./deploy.sh || ./rollback.sh

カナリアデプロイの導入:
一部のサーバーだけ先にデプロイしてテスト

ブルーグリーンデプロイ:
新旧2つの環境を切り替える方式

問題4:セキュリティの問題

症状:
秘密情報が漏洩するリスク

対策:

秘密情報のスキャン:

- name: Secret scan
  run: |
    git secrets --scan

依存関係の脆弱性チェック:

- name: Security audit
  run: npm audit

アクセス権限の最小化:
必要最小限の権限だけ付与する

問題5:コストが高い

症状:
CI/CDの実行時間がかさんで費用が増加

解決策:

不要なパイプラインを削減:
ドラフトPRではCI実行をスキップ

ビルド時間の最適化:
キャッシュと並列化を徹底

安価なランナーの選択:
必要なスペックだけを選ぶ


セキュリティを考慮したCI/CD

依存関係のスキャン

脆弱性チェックの例:

security_scan:
  stage: test
  script:
    # Node.jsの場合
    - npm audit

    # Pythonの場合
    - pip install safety
    - safety check

    # Rubyの場合
    - bundle audit

定期的に依存関係の脆弱性をチェックしましょう。

コード品質チェック

リンターとフォーマッター:

code_quality:
  stage: test
  script:
    # ESLint
    - npm run lint

    # Prettier
    - npm run format:check

    # SonarQube
    - sonar-scanner

コードの品質を自動でチェックできます。

シークレットスキャン

秘密情報の検出:

secret_detection:
  stage: test
  script:
    # GitLeaks
    - gitleaks detect --source . --verbose

    # TruffleHog
    - trufflehog filesystem .

誤ってコミットされた秘密情報を検出します。


実践例:実際のプロジェクトでの設定

フルスタックWebアプリケーション

フロントエンド + バックエンド + データベースの例:

name: Full Stack CI/CD

on:
  push:
    branches: [ main ]

jobs:
  # フロントエンドのテスト
  frontend_test:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./frontend
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-node@v3
      with:
        node-version: '18'
    - run: npm ci
    - run: npm test
    - run: npm run build

  # バックエンドのテスト
  backend_test:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./backend
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    - run: |
        pip install -r requirements.txt
        python manage.py migrate
        python manage.py test

  # E2Eテスト
  e2e_test:
    needs: [frontend_test, backend_test]
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Run E2E tests
      run: |
        docker-compose up -d
        npm run test:e2e
        docker-compose down

  # デプロイ
  deploy:
    needs: e2e_test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Deploy to production
      env:
        DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
      run: |
        ./deploy.sh production

モバイルアプリのビルド

iOS/Androidの例:

name: Mobile App CI

on: [push]

jobs:
  build_android:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-java@v3
      with:
        distribution: 'temurin'
        java-version: '17'
    - name: Build Android
      run: |
        cd android
        ./gradlew assembleRelease
    - name: Upload APK
      uses: actions/upload-artifact@v3
      with:
        name: app-release.apk
        path: android/app/build/outputs/apk/release/

  build_ios:
    runs-on: macos-latest
    steps:
    - uses: actions/checkout@v3
    - name: Setup Xcode
      uses: maxim-lobanov/setup-xcode@v1
      with:
        xcode-version: latest-stable
    - name: Build iOS
      run: |
        cd ios
        xcodebuild -scheme MyApp -configuration Release

macOSランナーが必要なので、コストは高めですが、iOS開発には必須ですね。


モニタリングとメトリクス

パイプラインのメトリクス測定

重要な指標:

デプロイ頻度
どのくらいの頻度でリリースしているか

変更のリードタイム
コミットから本番環境までの時間

変更失敗率
デプロイがどのくらい失敗しているか

復旧時間
障害から復旧するまでの時間

これらの指標を定期的にモニタリングして、改善につなげましょう。

通知とアラート

Slack通知の例:

- name: Slack Notification
  if: always()
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    text: 'デプロイが${{ job.status }}しました'
    webhook_url: ${{ secrets.SLACK_WEBHOOK }}

成功・失敗に関わらず、チームに状況を共有することが大切です。


まとめ

CI/CD設定は、現代のソフトウェア開発に不可欠な自動化の仕組みです。

この記事のポイント:

  • CI/CDは開発からデプロイまでを自動化する仕組み
  • CIはコードの統合とテスト、CDはデプロイの自動化
  • GitHub Actions、GitLab CI、Jenkinsなど様々なツールがある
  • トリガー、ジョブ、ステップで構成される
  • テスト、ビルド、デプロイの3段階が基本
  • 小さく頻繁にコミットすることが重要
  • セキュリティと速度を両立させる
  • 環境変数と秘密情報の管理を徹底する

最初は設定が難しく感じるかもしれませんが、一度構築してしまえば、開発効率が劇的に向上します。

まずはシンプルな自動テストから始めて、徐々に自動デプロイへと拡張していくのがおすすめですよ。

手作業から解放されて、本当に価値のある開発に集中できるようになるはずです。

さあ、あなたのプロジェクトにもCI/CDを導入して、開発体験を向上させてみませんか?自動化の恩恵を実感できますよ!

コメント

タイトルとURLをコピーしました