0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CircleCI で SSH デバッグを使う: ローカル再現できない CI エラーを直接調査する方法

0
Posted at

ローカルでは成功するテストやビルドが、CircleCI 上でのみ失敗するケースがあります。原因の多くは、環境変数の設定不一致、ランタイムやライブラリのバージョン差異、.gitignore で除外されたファイルの不在といった、ローカル環境と CI 実行環境の差分にあります。

こうした環境差分を切り分けるためにログ出力を追加して再実行を繰り返すと、1 サイクルあたりのビルド待ち時間が積み上がります。

CircleCI には、失敗したジョブと同じ環境に SSH で接続し、環境変数・ファイル・プロセスを直接調査できる SSH デバッグ機能(Rerun job with SSH) があります。

本記事では、SSH デバッグの基本的な実行手順、環境差分起因の CI エラーを切り分ける具体的な調査コマンドなどについて紹介します。

SSH デバッグとは

SSH デバッグは、失敗したジョブと同じ環境(同じ VM、同じコンテナ)に SSH で接続できる CircleCI の機能です。「ログ出力を追加して再実行する」のではなく「失敗時の状態に入って観察する」というアプローチを取ります。接続後の環境では、環境変数の実際の値、ローカルとのランタイムバージョンの差異、ファイルやディレクトリの状態と権限を直接確認できます。

ログ追加・push・再実行のサイクルは 1 回あたり数分のビルド待ちが発生しますが、SSH 接続後は実行環境上で複数の調査コマンドを連続して実行できるため、調査時間を短縮できます。

CircleCIでSSH デバッグを実行する

1. ジョブを SSH 付きで再実行する

失敗したジョブの詳細画面(ワークフロー画面ではなく、個別のジョブ画面)を開き、画面右上の Rerun ドロップダウンから Rerun job with SSH を選択します。同じパイプライン内に新しいジョブが起動し、SSH 接続を待ち受ける状態になります。

Rerun job with SSH メニュー

2. 接続コマンドを取得する

ジョブが起動すると、ジョブ出力に Enable SSH セクションが追加されます。これをクリックすると、SSH 接続用のコマンドが表示されます。

Enable SSH セクションの接続コマンド

接続コマンドは以下の形式で提示されます。ポート番号と IP アドレスはジョブごとに動的に割り当てられるため、毎回 Enable SSH セクションから取得します。

ssh -p 35359 12.345.678.901

同じ情報がジョブ末尾の Wait for SSH セクションにも表示されます。

3. 接続して調査する

ターミナルから接続コマンドを実行します。初回接続時は host key の確認プロンプトが表示されます。

$ ssh -p 35359 12.345.678.901
The authenticity of host '[12.345.678.901]:35359 ([12.345.678.901]:35359)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
circleci@76e1c0b3531b:~$

接続直後はホームディレクトリに着地します。Docker executor の場合、ユーザー名は circleci で、リポジトリは ~/project/ 配下に展開されています。

circleci@76e1c0b3531b:~$ ls -la
total 20
drwxr-x--- 1 circleci circleci   82 Apr 27 05:57 .
drwxr-xr-x 1 root     root       22 Feb 29  2024 ..
-rw-r--r-- 1 circleci circleci  220 Jan  6  2022 .bash_logout
-rw-r--r-- 1 circleci circleci 3771 Jan  6  2022 .bashrc
drwxrwxr-x 2 circleci circleci    6 Feb 29  2024 bin
drwxrwxr-x 1 circleci circleci 4096 Apr 27 05:57 project

調査対象のリポジトリへ移動してから、各種調査コマンドを実行します。

circleci@76e1c0b3531b:~$ cd project
circleci@76e1c0b3531b:~/project$ ls -la

4. 切断とジョブの停止

調査が終わったら exit で SSH セッションを切断します。SSH の切断だけではジョブが終了しません。

ジョブ詳細画面右上の Rerun ドロップダウンを開き、最下部の Cancel job を選択しましょう。

Rerun ドロップダウン内の Cancel job

これでジョブが停止します。

SSHデバッグを利用した調査の例

SSHデバッグ機能を使ってCIを調査する例を3つほど紹介します。

環境変数が反映されていないケース

ローカル環境では動作するジョブがCIでのみ失敗する場合、環境変数の設定が漏れている可能性があります。特にCircleCIの場合、Contextを利用して環境変数を登録しているケースで、セキュリティグループによる制限が設定されているケースで起こりがちです。

SSH 接続後、printenv で期待する環境変数が設定されているかを確認しましょう。

# 期待する環境変数が設定されているか確認
circleci@76e1c0b3531b:~$ printenv | grep DATABASE_URL

# 環境変数の一覧を確認し、似た名前の変数がないかも合わせて確認
circleci@76e1c0b3531b:~$ printenv | sort | less

printenv | grep の出力が空であれば、変数が CI 環境に届いていません。

このケースで確認すべきポイントは 3 つあります。1 つ目は Project Settings の Environment Variables に対象の変数が登録されているかです。2 つ目は .circleci/config.yml のジョブ定義で適切な Context が参照されているかです。3 つ目は参照している Context が組織内で適切なセキュリティグループに紐づいているかです。

printenv の出力には Context 経由で注入された変数も含まれるため、SSH 接続後にこの一覧を確認することで、Project Settings 側の設定漏れなのか、config.yml 側の Context 参照漏れなのかをその場で切り分けられます。

ランタイムバージョンの差異が疑われるケース

ローカルで成功するテストが CI で失敗する場合、テストフレームワークの挙動差異や、言語ランタイムのマイナーバージョン差が原因となるケースがあります。SSH 接続後、実行環境の OS とランタイムバージョンを確認します。

# 実行環境の OS を確認
circleci@76e1c0b3531b:~$ cat /etc/os-release

# 使用しているランタイムのバージョンを確認(環境に応じて使い分け)
circleci@76e1c0b3531b:~$ php -v
PHP 8.3.30 (cli) (built: Jan 14 2026 04:47:13) (NTS)

circleci@76e1c0b3531b:~$ python --version
circleci@76e1c0b3531b:~$ node --version
circleci@76e1c0b3531b:~$ ruby --version

ここで注意が必要なのは、実行環境にインストールされていないランタイムは存在しないという点です。たとえば PHP 用の Docker image を executor に指定しているジョブでは、node コマンドは存在しません。

circleci@76e1c0b3531b:~$ node --version
-bash: node: command not found

ローカルとの差異を確認する際は、ローカル環境でも同じコマンドを実行してバージョン文字列を突き合わせましょう。

ファイルの不在や権限の差異が疑われるケース

ファイル読み込みエラーや権限エラーが CI でだけ発生する場合、.env.xxx のように .gitignore で除外されているファイルが CI 環境に存在しないケース、もしくはファイルは存在するが権限が想定と異なるケースが疑われます。SSH 接続後、対象ファイルの存在・権限・内容を順に確認します。

# プロジェクトディレクトリに移動
circleci@76e1c0b3531b:~$ cd ~/project

# 対象ファイルが存在するか、権限はどうなっているか
circleci@76e1c0b3531b:~/project$ ls -la path/to/file

# .env ファイルの存在を確認(CI では .gitignore で除外されていることが多い)
circleci@76e1c0b3531b:~/project$ ls -la .env.prod

# ファイルの中身を確認
circleci@76e1c0b3531b:~/project$ cat path/to/config.yml

これらの確認により、ファイルが不在なのか、権限が想定と異なるのか、内容が異なるのかを切り分けられます。

SSH デバッグ実行環境の制限

SSH デバッグ実行中のジョブは、明示的にキャンセルするかタイムアウトするまで動作し続けます。タイムアウトの条件は以下の2つです。

  • パイプライン完了後、SSH 接続が一度も行われなければ 10 分で自動シャットダウンされます
  • SSH 接続後の VM 保持時間は最大 2 時間(Free プランは 1 時間)です

接続せずに放置した場合は 10 分で自動的に解放されます。一方、一度でも接続した後は最大 2 時間 VM が残るため、複数の SSH リランを起動して停止し忘れていると、organization の concurrency 枠が埋まり、他のパイプラインがキューで待機する状態が発生します。

まとめ

CircleCI の SSH デバッグは、ローカル再現できない CI エラーの調査を、ログ追加・push・確認のサイクルから、失敗時の状態に直接入って観察するアプローチに切り替える機能です。CI エラーの問題調査方法として、ローカルでの再現テストと組み合わせてご活用ください。

参考リソース

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?