컨테이너 레지스트리에 컨테이너 이미지 빌드 및 푸시
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
컨테이너 이미지를 빌드하고 푸시하기 전에 컨테이너 레지스트리로 인증해야 합니다. Docker 명령을 사용하여 컨테이너 레지스트리에 컨테이너 이미지를 빌드하고 푸시할 수 있습니다: 빌드 또는 푸시를 위한 Docker 명령을 실행합니다.
컨테이너 이미지를 빌드하고 푸시하기 전에 컨테이너 레지스트리로 인증해야 합니다.
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을 수행합니다. 이 단계는 이미지를 로컬로 캐시하는 여러 러너를 사용하는 경우 특히 중요합니다.이미지 태그에 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 host
GitLab CI/CD를 사용한 컨테이너 레지스트리 예시#
러너에서 DinD를 사용하는 경우 .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 작업을 병렬로 실행되는 두 개의 테스트를 포함하여 네 개의 파이프라인 단계로 분리합니다.
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:
# TLS 사용 https://docs.gitlab.com/ci/docker/using_docker_build/#use-docker-in-docker
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 실행기를 사용하려면 pull_policy가 always로 설정되어 있는지 확인하세요.
