コンテナイメージをビルドしてコンテナレジストリにプッシュする
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
コンテナイメージをビルドしてプッシュする前に、コンテナレジストリで認証する必要があります。
Dockerコマンドを使用する
Dockerコマンドを使用して、コンテナイメージをコンテナレジストリにビルドおよびプッシュできます:
コンテナレジストリで認証します。
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パイプラインからコンテナ化されたアプリケーションをビルド、テスト、およびデプロイします。
前提要件:
- Docker-in-Dockerを設定します。
GitLabコンテナレジストリに格納されているイメージを使用する場合は、このアプローチを使用します。
.gitlab-ci.ymlファイルでは、:
imageとservicesを更新して、レジストリを指すようにしてください。- サービスエイリアスを追加します。
.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ファイルでは、:
imageとservicesを更新して、依存プロキシのプレフィックスを使用します。- サービスエイリアスを追加します。
.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 hostGitLab 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_policyがalwaysに設定されていることを確認してください。