CI/CDベストプラクティス2026 — GitHub Actions, GitLab CI, CircleCI
CI/CDとは
CI/CD(Continuous Integration / Continuous Delivery)は、コードの変更を自動的にテスト・ビルド・デプロイするための仕組みです。
CI(継続的インテグレーション)
コードをリポジトリにプッシュするたびに、自動的にテスト・ビルドを実行します。
- コードの品質を保つ
- バグを早期に発見
- チーム開発をスムーズに
CD(継続的デリバリー/デプロイ)
テストが通ったコードを自動的に本番環境にデプロイします。
- デプロイの自動化
- リリースサイクルの短縮
- 人為的ミスの削減
各プラットフォーム比較
GitHub Actions
特徴
- GitHub完全統合
- YAMLで設定
- マーケットプレイスが豊富
- 無料枠が大きい
料金
- Public: 無制限
- Private: 2,000分/月(無料)、追加$0.008/分
メリット
- GitHubとの統合が最強
- セットアップが簡単
- コミュニティが活発
- Actionマーケットプレイスが便利
デメリット
- 高度な機能は他サービスに劣る
- ログの保存期間が短い(90日)
- セルフホストランナーの管理が必要な場合も
推奨する人
- GitHubをメインで使っている
- 簡単にCI/CDを始めたい
- オープンソースプロジェクト
GitLab CI
特徴
- GitLab完全統合
- .gitlab-ci.ymlで設定
- セルフホスト可能
- 強力なDevOps機能
料金
- Free: 400分/月
- Premium: $29/ユーザー/月
- Ultimate: $99/ユーザー/月
メリット
- GitLabとの統合が完璧
- セルフホストで完全制御可能
- 高度なCI/CD機能(親子パイプライン等)
- Auto DevOps(自動設定)
デメリット
- GitHubユーザーには敷居が高い
- 無料枠が少ない
- セルフホストは運用コストがかかる
推奨する人
- GitLabをメインで使っている
- セルフホストしたい
- エンタープライズ向け
CircleCI
特徴
- GitHub/GitLab/Bitbucket対応
- config.ymlで設定
- 高速なビルド
- 強力なキャッシュ機能
料金
- Free: 6,000分/月(1コンテナ)
- Performance: $15/月〜
- Scale: カスタム
メリット
- ビルドが高速
- キャッシュ機能が優秀
- Orbsで再利用可能な設定
- Docker Layerキャッシュ
デメリット
- 設定が複雑
- 無料枠は1コンテナのみ
- 料金が高め
推奨する人
- 大規模プロジェクト
- ビルド速度を重視
- 複雑なパイプラインが必要
CI/CDパイプライン設計
基本的なパイプライン
Code Push → Lint → Test → Build → Deploy
推奨パイプライン構造
# GitHub Actionsの例
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Test
run: npm test
- name: Upload coverage
uses: codecov/codecov-action@v4
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: build
path: dist/
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: build
- 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 }}
マルチ環境デプロイ
deploy-staging:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/develop'
steps:
- name: Deploy to Staging
run: |
echo "Deploying to staging..."
deploy-production:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to Production
run: |
echo "Deploying to production..."
キャッシュ戦略
キャッシュを活用すれば、ビルド時間を大幅に短縮できます。
GitHub Actionsのキャッシュ
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
Node.js依存関係のキャッシュ
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # 自動でキャッシュ
Dockerレイヤーキャッシュ
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: user/app:latest
cache-from: type=gha
cache-to: type=gha,mode=max
GitLab CIのキャッシュ
cache:
key: ${CI_COMMIT_REF_SLUG}
paths:
- node_modules/
- .npm/
before_script:
- npm ci --cache .npm --prefer-offline
CircleCIのキャッシュ
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package-lock.json" }}
- v1-dependencies-
- run: npm install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package-lock.json" }}
セキュリティベストプラクティス
シークレット管理
GitHub Actions
- name: Deploy
env:
API_KEY: ${{ secrets.API_KEY }}
run: |
echo "Deploying with API key..."
シークレットはリポジトリの Settings > Secrets で管理します。
環境変数の暗号化
# GitHub CLI
gh secret set API_KEY
SAST(静的アプリケーションセキュリティテスト)
Semgrep
- name: Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/secrets
CodeQL(GitHub)
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
DAST(動的アプリケーションセキュリティテスト)
OWASP ZAP
- name: ZAP Scan
uses: zaproxy/action-baseline@v0.12.0
with:
target: 'https://staging.example.com'
依存関係の脆弱性スキャン
Snyk
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
Dependabot(GitHub)
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
コンテナイメージスキャン
Trivy
- name: Run Trivy scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'user/app:latest'
format: 'sarif'
output: 'trivy-results.sarif'
デプロイ戦略
Blue-Green Deployment
2つの環境(BlueとGreen)を用意し、一方を本番、もう一方を次バージョンとして切り替えます。
メリット
- ダウンタイムゼロ
- すぐにロールバック可能
デメリット
- 2倍のリソースが必要
実装例(AWS ECS)
- name: Deploy to ECS
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: task-definition.json
service: my-service
cluster: my-cluster
wait-for-service-stability: true
deployment-configuration:
deployment-type: blue-green
Canary Deployment
新バージョンを少しずつリリースし、問題がなければ徐々に増やします。
メリット
- リスクが低い
- 段階的に検証できる
デメリット
- 複雑
- モニタリングが必須
実装例(Kubernetes)
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-stable
spec:
replicas: 9
selector:
matchLabels:
app: my-app
version: stable
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-canary
spec:
replicas: 1
selector:
matchLabels:
app: my-app
version: canary
Rolling Deployment
少しずつインスタンスを新バージョンに入れ替えます。
メリット
- 追加リソース不要
- 段階的にデプロイ
デメリット
- 古いバージョンと新バージョンが混在
実装例(Kubernetes)
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
モノレポのCI/CD
モノレポ(複数プロジェクトを1つのリポジトリで管理)では、変更があったプロジェクトだけビルド・デプロイします。
Turborepoを使った例
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
# 変更があったプロジェクトだけビルド
- name: Build
run: npx turbo run build --filter='[HEAD^1]'
# 変更があったプロジェクトだけテスト
- name: Test
run: npx turbo run test --filter='[HEAD^1]'
パスベースのフィルタリング
name: Deploy App1
on:
push:
paths:
- 'apps/app1/**'
- 'packages/**'
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy App1
run: |
echo "Deploying App1..."
まとめ
CI/CDは現代の開発に欠かせないインフラです。
プラットフォームの選び方
- GitHub: GitHub Actions
- GitLab: GitLab CI
- 速度重視: CircleCI
パイプライン設計のポイント
- 並列化できるジョブは並列化
- キャッシュを活用
- 早くフィードバック(Lintを最初に)
セキュリティ
- シークレットを安全に管理
- SAST/DASTを導入
- 依存関係をスキャン
デプロイ戦略
- ダウンタイムゼロ: Blue-Green
- リスク最小: Canary
- シンプル: Rolling
CI/CDを適切に設定すれば、開発効率とコード品質が大幅に向上します。