컨테이너 이미지를 빌드하고 레지스트리에 푸시하기

Tier: Free, Premium, Ultimate Offering: GitLab.com, 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.yml 파일 구성

.gitlab-ci.yml 파일을 구성하여 컨테이너 이미지를 빌드하고 레지스트리에 푸시할 수 있습니다.

  • 여러 작업에서 인증이 필요한 경우 before_script에 인증 명령을 넣으세요.
  • 빌드하기 전에 docker build --pull을 사용하여 기본 이미지의 변경 사항을 가져옵니다. 다소 시간이 걸리지만 이미지를 최신 상태로 유지할 수 있습니다.
  • docker run 전에 명시적으로 docker pull을 수행하여 방금 빌드된 이미지를 가져오세요. 여러 Runner를 사용하고 로컬로 이미지를 캐시하는 경우 특히 중요합니다.

    이미지 태그에 Git SHA를 사용하면 각 작업이 고유하며 오래된 이미지가 없어야 합니다. 그러나 특정 커밋을 재빌드하는 경우 의존성이 변경된 후 오래된 이미지가 생길 수 있습니다.

  • 여러 작업이 동시에 진행될 수 있으므로 latest 태그로 직접 빌드하지 마세요.

GitLab CI/CD 사용

GitLab CI/CD를 사용하여 컨테이너 이미지를 빌드하고 레지스트리에 푸시할 수 있습니다. CI/CD를 사용하여 프로젝트에서 만든 컨테이너 이미지를 테스트, 빌드 및 배포할 수 있습니다.

컨테이너 레지스트리 사용 예시와 GitLab CI/CD

Runner에서 Docker-in-Docker를 사용하는 경우 .gitlab-ci.yml 파일은 다음과 비슷해야 합니다:

build:
  image: $CI_REGISTRY/group/project/docker:20.10.16
  services:
    - name: $CI_REGISTRY/group/project/docker:20.10.16-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

의존성 프록시를 사용하는 Docker-in-Docker 컨테이너 이미지

의존성 프록시를 사용하는 컨테이너 이미지를 다음과 비슷하게 설정할 수 있습니다:

build:
  image: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:20.10.16
  services:
    - name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:18.09.7-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:20.10.16
  stage: build
  services:
    - docker:20.10.16-dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - 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:20.10.16
  stage: build
  services:
    - docker:20.10.16-dind
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG

이 예시에서 $CI_REGISTRY_IMAGE는 이 프로젝트에 연결된 레지스트리 주소로 해석됩니다. $CI_COMMIT_REF_NAME은 브랜치 또는 태그 이름으로, 슬래시를 포함할 수 있습니다. 이미지 태그에는 슬래시를 포함할 수 없습니다. 이미지 태그로 $CI_COMMIT_REF_SLUG를 사용하세요. script 섹션에서 타이핑을 줄이기 위해 $CI_REGISTRY_IMAGE$CI_COMMIT_REF_NAME을 결합하여 $IMAGE_TAG 변수를 선언할 수 있습니다.

이 예제는 작업을 4개의 파이프라인 단계로 분리하고 두 가지 테스트를 병렬로 실행하는 등의 작업을 수행합니다. 빌드는 컨테이너 레지스트리에 저장되며 필요할 때 컨테이너 이미지가 다운로드됩니다. main에 대한 변경 사항은 latest로 태그되며 애플리케이션별 배포 스크립트를 사용하여 배포됩니다.

default:
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

stages:
  - build
  - test
  - release
  - deploy

variables:
  # 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
  only:
    - main

deploy:
  stage: deploy
  script:
    - ./deploy.sh
  only:
    - main
  environment: production

참고: 이 예제에서는 명시적으로 docker pull을 호출합니다. image:을 사용하여 컨테이너 이미지를 암시적으로 가져오고 Docker 또는 Kubernetes 실행기를 사용하려는 경우 선언된 컨테이너 이미지가 필요할 때 항상 pull_policy가 설정되어 있는지 확인하십시오.