Bitbucket Pipelinesを「爆速」に変える:CI時間を削り倒すコンテナ最適化の極意
CI/CDが遅いということは、開発者の思考が中断されるということだ。Bitbucket Pipelinesの待機時間は、単なる待ち時間ではない。それは君たちのチームがイノベーションを起こすための貴重なリソースがドブに捨てられている時間だ。
今日は、Bitbucket Pipelinesにおいて「ビルドイメージの軽量化」と「キャッシュの極限利用」を通じて、CIパイプラインを秒速で回すための現場の知見を叩き込む。
—
1. マルチステージビルド:不要なものは一切持ち込まない
CIにおいて、「ビルド環境」と「実行環境」を混同してはいけない。Node.jsのビルドツール(webpackやesbuild)やコンパイラを最終的なイメージに残すのは、巨大なゴミを抱えて走るようなものだ。
最適化前:
FROM node:18
WORKDIR /app
COPY . .
RUN npm install && npm run build
この時点でnode_modulesやソースコードが含まれ、イメージが肥大化する
最適化後(マルチステージ):
ステージ1: ビルド環境
FROM node:18-alpine AS builder
WORKDIR /app
COPY package.json ./
RUN npm ci –prefer-offline # ciコマンドで再現性を確保
COPY . .
RUN npm run build
ステージ2: 実行環境(軽量版)
FROM nginx:alpine
ビルド成果物のみをコピーする「外科手術」
COPY –from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
ポイント: `npm ci` を使うこと。`npm install` は環境によって結果が変わる可能性があるが、`npm ci` は `package-lock.json` に厳密に従うため、CIでの事故を防ぐ。
—
2. Dockerレイヤーキャッシュの真実
Bitbucket Pipelinesで最大のボトルネックは「クリーンビルドの繰り返し」だ。キャッシュを効かせるには、`Dockerfile`の書き順がすべてを握る。
- 依存関係の定義を先にコピー: `package.json` や `go.mod` だけを先にコピーし、`RUN npm install` などを実行してから、ソースコードをコピーする。
- 変更頻度の低いものを上に: これにより、ソースコードを修正しても依存関係のレイヤーは再利用される。
Bitbucket Pipelinesでのキャッシュ設定(bitbucket-pipelines.yml)
definitions:
caches:
# カスタムキャッシュを定義して、node_modulesを永続化する
node: ~/.npm
pipelines:
default:
- step:
caches:
- node
script:
- npm ci
- npm run build
—
3. Alpine Linux:迷わずこれを選べ
Ubuntuベースのイメージは機能豊富だが、CIには過剰だ。`alpine`を選択するだけで、イメージサイズは数分の一になる。プルにかかる時間(Pull Time)を劇的に短縮できる。
- 注意点: Alpineは `musl libc` を使用している。ネイティブ依存のライブラリ(PythonのC拡張やNodeのバイナリなど)を使う場合は、予期せぬ動作をすることがある。その場合は、`debian-slim` を検討せよ。
—
4. チームで共有すべき「神」設定とルール
チーム開発のベストプラクティス
1. `.dockerignore` の徹底:
`.git`, `node_modules`, `.vscode`, `tmp` などの不要なディレクトリをコンテナ内に持ち込ませない。これだけでイメージサイズは数MBから数GB変わる。
2. `–no-cache` を不用意に使わない:
テストやデバッグで `docker build –no-cache` を常用するな。パイプラインの定義では、キャッシュを活用する構成こそが正義だ。
3. シークレット管理:
`bitbucket-pipelines.yml` にトークンをハードコードするな。リポジトリ設定の「Repository variables」を使い、セキュアに環境変数を注入しろ。
—
5. 現場で役立つ隠れたテクニック
A. ビルドコマンドのショートカット
頻繁に叩くビルドコマンドは `package.json` の `scripts` に集約し、さらにローカル環境では `alias` を設定せよ。
.zshrcや.bashrcに記述
alias bbp=”git push origin HEAD” # プッシュしてパイプラインを即座に走らせる
B. Bitbucket Pipelinesの「神」プラグイン・機能
- `pipe` を活用せよ: 自前で複雑なシェルを書く必要はない。Bitbucket公式が提供する `pipe`(例: `atlassian/docker-push`)を使うことで、認証やエラーハンドリングを自動化できる。
- `parallel` ステップ: 重いテストとビルドは、`parallel` を使って並列実行しろ。CI時間が半分になる。
pipelines:
branches:
main:
- parallel:
- step:
name: Unit Tests
script: npm test
- step:
name: Linting & Security Scan
script: npm run lint
—
最後に:エンジニアへのメッセージ
CI/CDパイプラインは、君の書いたコードに対する「最初のユーザー」だ。パイプラインが遅いと、君のコードの質は下がる。なぜなら、改善のサイクルが遅れるからだ。
今日紹介したテクニックは、どれも地味に見えるかもしれない。だが、「コンテナを最適化し、キャッシュを制御し、並列化する」という基本を極めた先には、秒単位でデプロイが完了するストレスフリーな開発体験が待っている。
さあ、今すぐ `bitbucket-pipelines.yml` を開き、不要なレイヤーを削ぎ落としてくれ。君のチームの生産性は、君が作るパイプラインの速度で決まる。