Contents
Dockerとマイクロサービスを活用したCI/CDパイプラインの具体的手順
Dockerとマイクロサービスの組み合わせは、現代のソフトウェア開発において効率的なデプロイメントを実現する重要な技術です。しかし、CI/CDパイプラインを構築する際には、「イメージのビルド手順が明確でない」「依存関係が複雑化する」などの課題に直面することがあります。本記事では、GitHub ActionsとDockerを組み合わせて実装できる具体的なステップを解説し、マイクロサービス環境でのCI/CDパイプライン構築のノウハウをお伝えします。
Dockerイメージの構築手順
マイクロサービスアーキテクチャでは、各サービスごとに個別のDockerイメージを作成する必要があります。この際、ベースイメージの選定やマルチステージビルドの活用が不可欠です。以下に具体的な手順とサンプルコードを示します。
マルチステージビルドの最適化
マルチステージビルドは、開発環境と実行環境を分離し、イメージサイズの削減やセキュリティ強化に寄与します。以下にその手順と効果を比較表にまとめました。
| 項目 | 値 | 補足 |
|---|---|---|
| コンパイル環境 | build-stage |
ソースコードのビルドや依存関係インストール用 |
| 実行環境 | runtime-stage |
バイナリファイルと必要なライブラリのみを含む |
| イメージサイズ | 30%〜50%削減 | コンパイルツールを含まない最終ステージに分離 |
注意点:ベースイメージは
alpineやslimなど軽量なバージョンを選ぶことで、CI/CDパイプライン全体の速度向上が期待できます。
Dockerfileの基本構成例
Dockerfileはサービスごとに個別に作成し、共通するコンポーネントを分離することで保守性を高めます。たとえば、NginxサーバーとNode.jsアプリケーションそれぞれのDockerfileが以下のように記述されます。
Nginx用Dockerfile
|
1 2 3 4 5 6 |
# ベースイメージ選定(軽量なalpine版) FROM nginx:alpine # マルチステージビルドでコンパイル環境を分離 COPY --from=build-stage /app/dist /usr/share/nginx/html |
Node.js用Dockerfile
|
1 2 3 4 5 6 7 8 9 10 11 |
# ベースイメージ選定(Node.jsの最新バージョン) FROM node:20 # アプリケーションコードコピーと依存関係インストール COPY . /app WORKDIR /app RUN npm install --production # エントリーポイント設定 CMD ["node", "index.js"] |
GitHub Actionsでの自動ビルド設定
GitHub Actionsを用いることで、プルリクエスト時やmainブランチへのPush時に自動でビルド・テストを実行できるようになります。以下にワークフローYAMLファイルの構成例を示します。
ワークフローYAMLファイル構成例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
name: Docker CI/CD on: push: branches: - main pull_request: branches: - develop jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Build Docker image with BuildKit run: | docker build --build-arg BUILDKIT_FRONTEND=dockerfile.v0 --progress=plain -t my-microservice . docker tag my-microservice registry.mycompany.com/my-microservice:latest - name: Push to GitHub Container Registry (GHCR) env: GHCR_USER: ${{ secrets.GHCR_USER }} GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} run: | echo "$GHCR_TOKEN" | docker login ghcr.io -u "$GHCR_USER" --password-stdin docker push ghcr.io/username/my-microservice:latest |
ベストプラクティスとして、Docker BuildKitを活用することでビルドのパフォーマンス向上が期待でき、GitHub Container Registry (GHCR)はリポジトリと連携しやすく、セキュリティスキャンの自動化にも対応しています。
イベントハンドラ設定のポイント
- Pull Request時:
developブランチでの変更をテストする。 - Push時:本番環境向けに
mainブランチで自動ビルドとプッシュを実施。
マイクロサービス間の依存関係管理
マイクロサービスではサービス同士が連携するため、起動順序や通信テストの自動化が重要です。Docker Composeは依存関係を定義しやすく、GitHub Actionsでその起動順序を制御できます。
サービス起動順序の制御方法
-
Docker Composeでの依存サービス定義
docker-compose.ymlにdepends_onを記述することで、起動順序を指定できます。
yaml
services:
db:
image: postgres
app:
depends_on:
- db
build: . -
GitHub Actionsでの起動順序制御
GitHub Actionsのrunステップでサービスごとに実行順を分離し、依存関係を検出。
yaml - name: Start dependent services
run: |
docker-compose up -d db -
name: Build and test service
run: |
docker-compose build app
docker-compose run --rm app npm test
-
サービス間通信テストの自動化
curlやhttpieで各サービス間の通信を検証し、失敗時の通知を設定。
パイプラインのテスト段階設計
CI/CDパイプラインでは、ユニットテストと静的解析を組み込むことで、品質を確保します。GitHub Actionsで自動化し、テストが失敗した場合はビルドを停止するロジックも重要です。
ユニットテストと静的解析の実装例
-
ユニットテストの実行手順
bash
npm install jest --save-dev
npm test -
静的解析ツールの導入(ESLint)
bash
npx eslint . --ext .js,.ts -
GitHub Actionsでテスト失敗時にビルド停止する設定例
yaml - name: Run tests
run: |
npm test
if [ $? -ne 0 ]; then
echo "Tests failed!"
exit 1
fi
テストカバレッジの計測には
nycやistanbulなどのツールを活用し、85%以上のカバレッジを目指すことが推奨されます。
本番環境へのデプロイベストプラクティス
本番環境へのデプロイでは、ロールアウト戦略の選定やセキュリティスキャンが必須です。Kubernetesと連携させることで安定性を高められます。
ロールアウト戦略と監視設定
- Blue/Greenデプロイの実装手順
- 新しいバージョンを別環境に配置し、トラフィックを切り替える。
-
Kubernetesの
rollout set imageコマンドを使用。
bash
kubectl rollout set image deployment/my-service my-microservice=ghcr.io/username/my-microservice:v1.2.3 -
Health Checkの自動検出
-
プロベ(Liveness/Readiness Probe)を設定し、サービスが正常に動作しているかを監視。
yaml
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15 -
セキュリティスキャンの導入例(Clair)
- バージョン管理されたDockerイメージに対して、脆弱性をスキャン。
bash
clair scan ghcr.io/username/my-microservice:v1.2.3
セキュリティスキャンはビルド時に実行することを推奨します。Clairの導入手順は以下の通りです:
- ClairのDockerイメージをGitHubから取得。
clairコマンドでスキャンを行い、結果を自動的に通知するように設定。
実装後の課題共有と改善アプローチ
CI/CDパイプライン構築には、イメージプル失敗や依存サービスの競合などのトラブルが発生することがあります。読者からのフィードバックをもとに、共通の対応策として以下のような解決法があります。
よくあるトラブルシューティング事例
- イメージプル失敗
- 原因:認証情報が不正、またはリポジトリにアクセス権がない。
-
解決策:
docker loginコマンドで正しい認証情報を入力し、リポジトリのプライバシー設定を確認。 -
依存サービスの競合
- 原因:Docker ComposeやKubernetesで起動順序が不適切。
- 解決策:
depends_onやinitContainersを使って起動順序を明示的に管理。
Kubernetesでのロールアウト戦略の具体例
Kubernetesでは、ロールアウト方式に応じて異なる手順が必要です。以下に代表的な3つの戦略を比較します。
| 戦略 | 説明 | 用途 |
|---|---|---|
| Blue/Greenデプロイ | 新しいバージョンと現行バージョンを並列で運用し、トラフィックを切り替える。 | 高可用性が必要な環境 |
| Rolling Update | サービスを段階的に更新し、中断なしに変更を反映する。 | スケールが大きいクラスタでも安定したロールアウトが可能 |
| Canary Release | 一部のユーザーに新しいバージョンを提供し、問題がないことを確認後に本番環境全体へ適用。 | バグ検出やパフォーマンス監視が必要な場合 |
記事内で紹介したサンプルコードをベースに、自身のプロジェクトでCI/CDパイプラインを構築してみてください。実装中に出会った課題があれば、コメント欄で共有いただけると、今後の改善点としてとても参考になります。