正式なドキュメントは英語版であり、この日本語訳はAI支援翻訳により作成された参考用のものです。日本語訳の一部の内容は人間によるレビューがまだ行われていないため、翻訳のタイミングにより英語版との間に差異が生じることがあります。最新かつ正確な情報については、英語版をご参照ください。

コンテナイメージをビルドしてコンテナレジストリにプッシュする

  • プラン: Free、Premium、Ultimate
  • 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated

コンテナイメージをビルドしてプッシュする前に、コンテナレジストリで認証する必要があります。

Dockerコマンドを使用する

Dockerコマンドを使用して、コンテナイメージをコンテナレジストリにビルドおよびプッシュできます:

  1. コンテナレジストリで認証します。

  2. Dockerコマンドを実行して、ビルドまたはプッシュします。次に例を示します:

    • ビルドする:

      docker build -t registry.example.com/group/project/image .
    • プッシュする:

      docker push registry.example.com/group/project/image

GitLab CI/CDを使用する

GitLab CI/CDを使用して、コンテナイメージをビルド、プッシュ、テスト、およびコンテナレジストリからデプロイします。

.gitlab-ci.ymlファイルを設定する

.gitlab-ci.ymlファイルを設定して、コンテナイメージをコンテナレジストリにビルドおよびプッシュできます。

  • 複数のジョブで認証が必要な場合は、認証コマンドをbefore_scriptに入力します。

  • ビルドする前に、docker build --pullを使用してベースイメージへの変更を取得します。少し時間がかかりますが、イメージが最新の状態に保たれます。

  • docker runの前に、明示的なdocker pullを実行して、ビルドされたばかりのイメージを取得します。このステップは、イメージをローカルにキャッシュする複数のRunnerを使用している場合に特に重要です。

    イメージタグにGit SHAを使用すれば、各ジョブが一意になり、古いイメージが使用されるのを防ぐことができます。ただし、依存関係が変更された後に特定のコミットを再ビルドすると、古いイメージが使用される可能性があります。

  • 複数のジョブが同時に実行される可能性があるため、latestタグに直接ビルドしないでください。

Docker-in-Dockerコンテナイメージを使用する

コンテナレジストリまたは依存プロキシで、独自のDocker-in-Docker(DinD)コンテナイメージを使用できます。

DinDを使用して、CI/CDパイプラインからコンテナ化されたアプリケーションをビルド、テスト、およびデプロイします。

前提要件:

GitLabコンテナレジストリに格納されているイメージを使用する場合は、このアプローチを使用します。

.gitlab-ci.ymlファイルでは、:

  • imageservicesを更新して、レジストリを指すようにしてください。
  • サービスエイリアスを追加します。

.gitlab-ci.ymlは次のようになります:

build:
  image: $CI_REGISTRY/group/project/docker:24.0.5-cli
  services:
    - name: $CI_REGISTRY/group/project/docker:24.0.5-dind
      alias: docker
  stage: build
  script:
    - docker build -t my-docker-image .
    - docker run my-docker-image /script/to/run/tests

このアプローチを使用すると、ビルドを高速化し、レート制限を回避するために、Docker Hubのような外部レジストリからイメージをキャッシュできます。

.gitlab-ci.ymlファイルでは、:

  • imageservicesを更新して、依存プロキシのプレフィックスを使用します。
  • サービスエイリアスを追加します。

.gitlab-ci.ymlは次のようになります:

build:
  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:24.0.5-cli
  services:
    - name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:24.0.5-dind
      alias: docker
  stage: build
  script:
    - docker build -t my-docker-image .
    - docker run my-docker-image /script/to/run/tests

サービスエイリアスの設定を忘れると、コンテナイメージはdindサービスを見つけることができず、次のようなエラーが表示されます:

error during connect: Get http://docker:2376/v1.39/info: dial tcp: lookup docker on 192.168.0.1:53: no such host

GitLab CI/CDを使用したコンテナレジストリの例

RunnerでDocker-in-Dockerを使用している場合、.gitlab-ci.ymlファイルは次のようになります:

build:
  image: docker:24.0.5-cli
  stage: build
  services:
    - docker:24.0.5-dind
  script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
    - docker build -t $CI_REGISTRY/group/project/image:latest .
    - docker push $CI_REGISTRY/group/project/image:latest

.gitlab-ci.ymlファイルでCI/CD変数を使用できます。例:

build:
  image: docker:24.0.5-cli
  stage: build
  services:
    - docker:24.0.5-dind
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG

前の例では:

  • $CI_REGISTRY_IMAGEは、このプロジェクトに関連付けられたレジストリのアドレスに解決されます。
  • $IMAGE_TAGは、レジストリアドレスとイメージタグ付けである$CI_COMMIT_REF_SLUGを組み合わせたカスタム変数です。$CI_COMMIT_REF_NAME定義済み変数は、ブランチまたはタグ名に解決され、フォワードスラッシュを含めることができます。コンテナイメージのタグにフォワードスラッシュを含めることはできません。代わりに$CI_COMMIT_REF_SLUGを使用してください。

次の例では、CI/CDタスクを4つのパイプラインステージに分割し、2つのテストを並行して実行します。

buildはコンテナレジストリに保存され、後続のステージで使用され、必要に応じてコンテナイメージをダウンロードします。mainブランチに変更をプッシュすると、パイプラインはイメージにlatestというタグ名を付け、アプリケーション固有のデプロイスクリプトを使用してデプロイします:

default:
  image: docker:24.0.5-cli
  services:
    - docker:24.0.5-dind
  before_script:
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY -u $CI_REGISTRY_USER --password-stdin

stages:
  - build
  - test
  - release
  - deploy

variables:
  # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: "/certs"
  CONTAINER_TEST_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:latest

build:
  stage: build
  script:
    - docker build --pull -t $CONTAINER_TEST_IMAGE .
    - docker push $CONTAINER_TEST_IMAGE

test1:
  stage: test
  script:
    - docker pull $CONTAINER_TEST_IMAGE
    - docker run $CONTAINER_TEST_IMAGE /script/to/run/tests

test2:
  stage: test
  script:
    - docker pull $CONTAINER_TEST_IMAGE
    - docker run $CONTAINER_TEST_IMAGE /script/to/run/another/test

release-image:
  stage: release
  script:
    - docker pull $CONTAINER_TEST_IMAGE
    - docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
    - docker push $CONTAINER_RELEASE_IMAGE
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

deploy:
  stage: deploy
  script:
    - ./deploy.sh
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  environment: production

前の例では、docker pullを明示的に呼び出しています。image:を使用してコンテナイメージを暗黙的にプルし、DockerまたはKubernetes executorのいずれかを使用する場合は、pull_policyalwaysに設定されていることを確認してください。