GitLab Runner: Dockerイメージのビルド
StackheroランナーとDocker-in-Dockerを活用し、GitLab CI/CDパイプラインから効率的にDockerイメージをビルド&プッシュする方法
👋 Stackhero ドキュメントへようこそ!
Stackhero では、GitLab Runner cloud を簡単にご利用いただけるソリューションとしてご提供しています。GitLab CI/CD ジョブを効率的に処理できるよう設計されています。主な特長は以下の通りです:
- 無制限の CI/CD 分数:分単位の課金はありませんので、必要なときにいつでもパイプラインを実行できます。
- 複数ジョブの同時実行:複数のジョブを同時に実行し、パイプライン全体の処理速度を向上させます。
- Docker executor と Docker-in-Docker サポート:コンテナイメージのビルドやプッシュを効率化します。
- GitLab.com およびあらゆる セルフホスト型 GitLab インスタンスに対応。
- 高速な NVMe/SSD ディスクを搭載した プライベート専用 VM で、安定したビルド環境を提供します。
- 🇪🇺 ヨーロッパ および 🇺🇸 USA リージョンでご利用可能です。
時間を節約:最初の GitLab Runner を接続し、数分でパイプラインの実行を開始できます!
はじめに
Stackhero GitLab Runnerを利用すると、すべてのジョブはDocker executorによって新しいコンテナ内で実行されます。Docker-in-Docker(DinD)を有効にすることで、パイプライン内で直接Dockerイメージをビルドできます。この構成では、ジョブと並行してDockerデーモンが起動し、docker buildやdocker pushコマンドをCI/CDプロセスの一部として実行できるようになります。
すべての実行は無制限のCI/CD分の恩恵を受けます。ビルド回数に制限はなく、必要なだけ何度でもビルド可能です。ビルドキャッシュはランナー専用ディスクに保存されるため、繰り返しのビルド時には以前のレイヤーを再利用できます。これによりビルド時間が大幅に短縮され、パイプラインの完了も高速化されます。
Docker-in-DockerでDockerイメージをビルドする
以下のサンプル.gitlab-ci.ymlをリポジトリに追加できます。この設定は、プロジェクトルートのDockerfileをビルドします。
build-image:
stage: build
image: docker:29
services:
- docker:29-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker info
script:
# "my-image"を任意のイメージ名に置き換えてください:
- docker build -t my-image .
# 必要に応じて、ビルドしたイメージで簡単なテストを実行できます:
# - docker run --rm my-image /path/to/tests
この例ではDockerイメージのバージョン29を使用しています。新しいバージョンが利用可能な場合は、そちらを使用することもできます。最新のタグは公式Dockerイメージページで確認できます。
この構成では、docker:29-dindサービスがDockerデーモンを起動します。DOCKER_TLS_CERTDIR: "/certs"を設定することで、ジョブとDockerデーモン間の安全なTLS接続が有効になります。
GitLabコンテナレジストリへのプッシュ
GitLabは、パイプラインがプロジェクトのコンテナレジストリへ安全に認証・プッシュできるよう、事前定義された変数(CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD, CI_REGISTRY_IMAGE)を提供しています。追加のシークレットは不要です。
以下はイメージをビルドし、プッシュするジョブの例です:
build-and-push:
stage: build
image: docker:29
services:
- docker:29-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
script:
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
# デフォルトブランチの場合は"latest"タグでもプッシュできます:
- |
if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
docker tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" "$CI_REGISTRY_IMAGE:latest"
docker push "$CI_REGISTRY_IMAGE:latest"
fi
他のレジストリ(Docker Hubやプライベートレジストリなど)へプッシュする場合は、CI/CD変数として認証情報を保存し、同様にdocker loginで利用できます。
ビルドの高速化(キャッシュの活用)
ランナーのディスクはパイプライン間で永続化されるため、イメージレイヤーをビルドキャッシュとして再利用できます。これにより繰り返しのビルドが大幅に高速化されます。以下はそのための設定例です:
build-cached:
stage: build
image: docker:29
services:
- docker:29-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
script:
# キャッシュ用に最新イメージをプル(存在しない場合もOK):
- docker pull "$CI_REGISTRY_IMAGE:latest" || true
- docker build --cache-from "$CI_REGISTRY_IMAGE:latest" -t "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:latest"
この方法により、Dockerのレイヤーキャッシュを活用し、新規または変更されたレイヤーのみが再ビルドされます。
ジョブの並列実行
同時に実行できるジョブ数はご契約プランによって決まります。同じステージ内のジョブは、設定された並列数の上限まで同時に開始されます。これにより、複数の独立したジョブが並行して実行され、最も遅いジョブが完了した時点でステージ全体が終了します。逐次実行を待つ必要はありません。
例:
stages:
- test
unit:
stage: test
image: node:22
script: npm run test:unit
integration:
stage: test
image: node:22
script: npm run test:integration
e2e:
stage: test
image: node:22
script: npm run test:e2e
並列数(concurrency)を1以上に設定すると、unit、integration、e2eの各ジョブが同時に実行されます。
GitLab CI/CDパイプラインでのDockerイメージビルドの詳細については、公式GitLabドキュメント:Dockerビルドの利用をご参照ください。