こんにちは!開発現場で「あれ、なんでローカルでは動くのにCIだと落ちるんだ……?」と頭を抱えた夜はありませんか?
こんにちは、君の専属の先輩エンジニアです。今日は、多くの開発者が一度はハマるCircleCIでのビルドトラブルを華麗に解決するための、現場の生きた知見をたっぷり授けようと思う。
これをマスターすれば、謎のビルドエラーに何時間も溶かす絶望的な作業から解放されて、毎日のデプロイ作業が劇的に楽になりますよ。さあ、一緒に扉を開けよう。
—
そもそもCircleCIって何をするツールなの?
初心者に向けて一言で言うなら、CircleCIは「あなたの代わりに、24時間文句も言わずにテストやビルドを自動でやってくれる優秀なロボット執事」だ。
私たちがGitHubなどにコードを「プッシュ」した瞬間を察知し、クラウド上のまっさらな仮想環境(コンテナ)で `npm test` や `docker build` などを実行してくれる。ローカルPCの環境依存(「俺のPCでは動くんだけどな…」)を排除し、チーム開発の品質を担保するための要(かなめ)となるCI/CDツールなんだ。
—
最初の関門:精度高い「Hello World」的パイプラインを作ろう
まずは、CircleCIの基本のキ、設定ファイルを作ってみよう。
リポジトリのルートに `.circleci/config.yaml` というファイルを作成してほしい。
基本の `config.yaml` テンプレート
version: 2.1 # CircleCIのバージョン指定。基本は最新の2.1を使おう
ジョブ(一連の作業単位)を定義する場所
jobs:
build-and-test:
# 実行環境の指定(今回はNode.jsの公式Dockerイメージを使用)
docker:
- image: cimg/node:18.16.0
# 作業ディレクトリ
working_directory: ~/my-project
# 実際に実行するステップの並び
steps:
- checkout # GitHubからソースコードをコンテナに引っ張ってくる
- run:
name: “依存関係のインストール”
command: npm ci
- run:
name: “ユニットテストの実行”
command: npm test
ワークフロー(ジョブを実行する順番や条件の定義)
workflows:
version: 2
main-workflow:
jobs:
- build-and-test
【ここがポイント】
- `checkout` ステップでソースコードが綺麗にクローンされる。
- `npm ci` は、`package-lock.json` をベースに高速かつ確実に依存関係をインストールするプロの常識だ。
これが無事にグリーン(成功)になれば、君のプロジェクトのCI基盤は完成だ!
—
ここからが本番!ビルドが止まった時の「2大デバッグ奥義」
さて、ここからが本日のメインテーマだ。開発を進めると、必ず「原因不明のビルドエラー」に直面する。そんな時に使うべき、現場のエンジニアが愛してやまない2つの武器を紹介しよう。
—
奥義その1:SSH接続でCircleCIのコンテナ内を丸裸にする
「ログを見ても、なぜテストが失敗するのか全くわからない……」
そんな時は、失敗したビルドに対してSSHで直接ログインし、コンテナ内部を直接調査するのが一番の近道だ。
手順
1. CircleCIのWebダッシュボードで、失敗したビルドの該当ジョブ画面を開く。
2. 右上の 「Rerun」 ボタンのプルダウンから、「Rerun job with SSH」 を選択する。
3. ジョブが立ち上がったら、ステップの中に 「Enable SSH」 という項目が出現するので、そこを展開する。
4. そこに書かれているSSHコマンド(例: `ssh -p 54321 ubuntu@turnip.circleci.com`)をコピーし、自分のターミナルに貼り付けて実行する。
これで、CIが実行されていたまさにそのコンテナの内部に、君のPCから直接ログインできる。
コンテナ内での調査テクニック
SSHで入ったら、以下のコマンドで原因を突き止めよう。
ソースコードが置かれているディレクトリへ移動
cd ~/my-project
ローカルと同じようにテストを手動実行してみる
npm test
環境変数が意図通りに設定されているか確認する
printenv
「あ、ここにあの環境変数が足りてなかったんだ!」といった発見が、手に取るように分かるはずだ。調査が終わったら `exit` で抜け、ダッシュボードでジョブを完了させよう。
—
奥義その2:CircleCI CLIでローカルパイプラインテストを爆速化する
「わざわざGitHubにプッシュして、CIが回るのを数分待って……失敗したらまた修正してプッシュ……」
こんな非効率なループを回していないかい? CircleCI CLI を使えば、自分のPC(ローカル環境)上でCircleCIの設定ファイルをそのままテストできる。
1. CircleCI CLIのインストール(Macの場合)
Homebrewを使っていれば一瞬だ。
brew install circleci
2. ローカルでのバリデーション(構文チェック)
設定ファイルを書いたら、プッシュする前に必ず構文エラーがないかチェックしよう。
circleci config validate
これでYAMLのインデントミスや記述ミスを事前に防げる。
3. ローカルでのジョブ実行(圧倒的な時短)
なんと、ローカルのDockerを使って、CIのジョブをそのまま手元で実行できる。
circleci local execute –job build-and-test
これの何が凄いって、GitHubにプッシュする前の段階で、CircleCI環境での挙動を完全にシミュレートできることだ。爆速でトライ&エラーができるので、デバッグ効率が何倍にも跳ね上がる。
—
よくあるビルド失敗エラーへの処方箋
最後に、現場で本当によく遭遇する「あるあるエラー」と、そのスマートな対処法をまとめておくね。
1. 「Out of Memory (OOM Killed)」エラー
- 症状: テストの途中で、理由も告げられずジョブが突然強制終了する。
- 原因: デフォルトのコンテナスペック(特にテストやビルドでメモリを食うJava, Next.js, Docker in Dockerなど)のメモリ上限を超えてしまっている。
- 対策: `config.yaml` のresource_classを指定して、マシンスペックを上げよう。
jobs:
build-and-test:
docker:
- image: cimg/node:18.16.0
resource_class: large # medium, large, xlarge などに変更可能
2. 依存関係のキャッシュ切れ・競合
- 症状: ローカルでは動くのに、CIだと「モジュールが見つからない」と言われる。
- 原因: `node_modules` や `vendor` のキャッシュが古くなっている、またはキャッシュのキー設計が間違っている。
- 対策: CircleCIの `save_cache` と `restore_cache` を正しく設定するか、いっそ毎回 `npm ci` を走らせる方が、近年のモダンなクラウド環境ではキャッシュのヒット率とビルド時間のバランスが良いことが多い(下手に複雑なキャッシュを組むと、かえってバグの温床になる)。
—
おわりに
CI/CDのトラブルシューティングは、最初は黒魔術のように感じるかもしれない。しかし、「SSHで中に入る」「CLIでローカル実行する」という2つの強力な武器を手に入れた君にとって、もはや恐れるものは何もないはずだ。
エラーが出たら、「お、コンテナの中を探索する楽しみが増えたぞ」とニヤリと笑えるくらいになれば、もう君はりっぱなDevOpsエンジニアだ。
この知見が、君の毎日の開発ライフを少しでも快適でエキサイティングなものに変えられますように。さあ、今日も最高のコードをデプロイしよう!