GitHub Actions の docker compose がイメージの pull で遅い:毎回 pull しないで済ませる方法
GitHub Actions で docker compose up が毎回すべてのイメージを pull するのは、GitHub ホストランナーのジョブが毎回新しい VM で始まるからです。Postgres、Redis、メッセージキュー、自分のサービスのイメージ。どれもディスクにないので、最初のテストが動く前に、Compose がすべてをダウンロードして展開します。同じイメージを毎回 pull しないで済ませる方法は 1つ。イメージが残っているマシンでジョブを動かすことです。
Skipbox が、そのマシンです。ジョブはアカウント専用のマシンで動き、Docker のイメージ、レイヤー、ビルドキャッシュがジョブのあとも残ります。docker compose up は前に pull したイメージを見つけて、そのままコンテナを起動します。書き換えるのは runs-on: skipbox の 1行。料金は月 6,000 円の定額で、実行時間は無制限です。
毎回 pull が走る理由
- ジョブごとに新しい VM。 GitHub のランナーのリファレンス(2026年11月14日に確認)のとおり、GitHub ホストランナーはどれも GitHub が用意する新しい仮想マシンです。前のジョブが pull したものは、そこにありません。
- Compose は、ないイメージを pull する。
pull_policyの既定はmissingで、イメージがマシンにないときだけ pull します。新しい VM では、すべてのイメージが「ない」です。 - pull はダウンロードと展開。 レイヤーを 1つずつダウンロードし、解凍して、VM のディスクに書き込みます。プライベートリポジトリの
ubuntu-latestは 2 CPU、SSD 14 GB です。
最初のテストが始まるまでの時間は、compose ファイルの大きさで決まります。それを push のたびに、毎回払っています。
GitHub ホストランナーでできること
どれもダウンロードの場所を移すだけで、なくすことはできません。
| 方法 | ジョブが毎回すること | 限界 |
|---|---|---|
docker save + actions/cache + docker load | アーカイブをダウンロードし、すべてのイメージを Docker に読み込む | GitHub のリポジトリごと 10 GB の枠を、ほかのキャッシュと分け合う |
小さいイメージ(-alpine、-slim)にする | 全部 pull する。少し速くなる | 小さい版のあるイメージだけ |
| ジョブごとのサービスを減らす | pull するイメージが減る | 全部のサービスが要るテストは、全部 pull する |
忘れるマシンに、少しだけ覚えさせる工夫です。pull がなくなるのは、マシンが覚えているときだけです。
Skipbox なら、イメージがマシンに残る
プランごとに、アカウント専用のマシンが付き、ジョブのあとも残ります。
- イメージはディスクに残ります。
docker compose upは前に pull したイメージを見つけ、すぐにコンテナの起動に進みます。 - ダウンロードするのは変わったぶんだけ。
docker compose pullは変わったレイヤーだけを取ってきて、残りはそのまま使います。 - 自分のサービスのイメージはキャッシュからビルド。
docker compose buildは前のビルドのレイヤーを使います。cache-fromもcache-toも要りません。 - ジョブは毎回きれいな状態から。 ジョブが終わるたびに、Skipbox がすべてのコンテナを消し、レジストリへのログイン(
~/.docker/config.json)も消します。次のジョブは、ディスクにあるイメージからサービスを新しく起動します。 - 置き場所も十分。 ディスクは S で 80 GB。GitHub のランナーは 14 GB です。ジョブのあとでディスクがほぼいっぱいになるまで何も消しません。いっぱいになったら、まずタグのないイメージを、次に使われたのがいちばん古いビルドキャッシュから消します。
ワークフローで変えるのは runs-on だけです。
jobs:
integration:
runs-on: skipbox # ubuntu-latest から書き換える
steps:
- uses: actions/checkout@v4
- run: docker compose up -d --wait
- run: npm ci && npm run test:integration
actions/cache と docker load でイメージを保存していたなら、そのステップは消してください。Skipbox での最初のジョブは、すべてのイメージを 1 回だけ pull します。2 回目は、それをマシンの上で見つけます。
マシンの大きさは、ジョブのラベルで選びます。
| ラベル | マシン | ディスク | プラン |
|---|---|---|---|
skipbox | 4 vCPU・メモリ 16 GB | 80 GB | S、月 6,000 円 |
skipbox-8x16 | 8 vCPU・メモリ 16 GB | 160 GB | M、月 12,000 円 |
skipbox-16x32 | 16 vCPU・メモリ 32 GB | 320 GB | L、月 23,000 円 |
同じ分数を、定額で
結合テストは時間のかかるジョブです。分課金の請求を押し上げるのも、このジョブです。Skipbox なら、実行時間は無制限です。
| 月の実行時間(4 vCPU) | GitHub | Skipbox S | 毎月の差額 |
|---|---|---|---|
| 10,000分 | 参考値:2026年11月10日の為替レート・1ドル=158.22円。米ドルの料金を、このレートで円に換算した概算です。 | 6,000 円 | 参考値:2026年11月10日の為替レート・1ドル=158.22円。米ドルの料金を、このレートで円に換算した概算です。 |
| 20,000分 | 参考値:2026年11月10日の為替レート・1ドル=158.22円。米ドルの料金を、このレートで円に換算した概算です。 | 6,000 円 | 参考値:2026年11月10日の為替レート・1ドル=158.22円。米ドルの料金を、このレートで円に換算した概算です。 |
| 30,000分 | 参考値:2026年11月10日の為替レート・1ドル=158.22円。米ドルの料金を、このレートで円に換算した概算です。 | 6,000 円 | 参考値:2026年11月10日の為替レート・1ドル=158.22円。米ドルの料金を、このレートで円に換算した概算です。 |
GitHub の額は、GitHub Team に含まれる無料分を引いたあとの請求です。自分のチームの分数で計算するなら、トップページの料金計算に入れてください。
移行は runs-on を 1行書き換えるだけ
- Skipbox に GitHub でログインする
- Skipbox の GitHub アプリを入れて、使うリポジトリを選ぶ
- 結合テストのジョブの
runs-onを書き換えて push する
同じワークフローでイメージもビルドしているなら、docker build と buildx のことは Docker のレイヤーキャッシュのガイドにあります。
セキュリティ
- マシンはアカウントごとの専用です。ほかの会社のジョブと同じマシンで動くことはありません。
- ジョブが終わるたびに、ランナーの認証情報、プロセスとコンテナを消し、
~/.docker/config.jsonも消すので、レジストリへのログインが次のジョブに残ることはありません。「毎回クリーン」なら、ジョブごとに新しいマシンで動きます。 - 書き込み権限のない人のコード(フォークからのプルリクエストなど)は、使い捨ての新しいマシンで動き、専用のマシンには来ません。
くわしくはジョブの分離のしくみにあります。
自分の結合テストで試す
カード不要で、7日間かジョブの合計 3,000分まで無料です。ジョブを runs-on: skipbox に替えて 2 回動かし、2 回目の docker compose up を GitHub と比べてください。
よくある質問
GitHub Actions の docker compose を使ったテストがイメージの pull で遅い。毎回 pull しないで済ませる方法はある?
あります。ディスクが残るマシンでジョブを動かすことです。GitHub ホストランナーはジョブごとに新しい VM なので、イメージは 1つも残らず、compose は毎回すべてを pull します。Skipbox ではジョブがアカウント専用のマシンで動き、Docker のイメージがジョブのあとも残ります。docker compose up は前に pull したイメージを見つけて、そのままコンテナを起動します。変更は runs-on: skipbox の 1行で、月 6,000 円の定額、実行時間は無制限です。
GitHub Actions で docker compose が毎回イメージを pull するのはなぜ?
Compose は、マシンにないイメージを pull します。そして GitHub ホストランナーには、いつも何もありません。GitHub のランナーのリファレンスのとおり、GitHub ホストランナーはどれも新しい仮想マシンで、前のジョブが pull したものは残っていません。Compose の pull_policy の既定は missing なので、イメージがあれば pull は飛ばされます。
docker compose のイメージを actions/cache でキャッシュできる?
できますが、ダウンロードの場所が移るだけです。docker save でイメージを tar にし、actions/cache で保存して、次のジョブで復元して docker load します。毎回アーカイブを丸ごとダウンロードして Docker に読み込むことになり、アーカイブは GitHub のリポジトリごと 10 GB の枠を、依存パッケージのキャッシュと分け合います。ディスクが残るマシンなら、保存するものも読み込むものもありません。
Skipbox では Docker のイメージがジョブのあとも残る?
残ります。プランごとにアカウント専用のマシンが付き、Docker のイメージ、レイヤー、ビルドキャッシュをディスクに残します。ディスクは S で 80 GB、M で 160 GB、L で 320 GB です。ジョブが終わるたびにコンテナとレジストリへのログインは消しますが、イメージは残ります。
compose のイメージが更新されたときはどうなる?
変わったレイヤーだけをダウンロードします。ジョブのたびにレジストリを確かめたいなら、docker compose up の前に docker compose pull を入れてください。Docker は新しいレイヤーだけを取ってきて、残りはマシンのディスクにあるものを使います。docker compose build でビルドする自分のイメージも、同じように前のビルドのレイヤーを使います。
試すのにお金はかかる?
かかりません。カード不要で、7日間かジョブの合計 3,000分まで無料です。結合テストのジョブを runs-on: skipbox に替えて 2 回動かし、2 回目の docker compose up を GitHub と比べてください。
2026年11月14日 更新