컨테이너 이미지를 빌드하고 컨테이너 레지스트리에 푸시하기
컨테이너 이미지를 빌드하고 푸시하기 전에 컨테이너 레지스트리와 인증해야 합니다.
Docker 명령어 사용
Docker 명령어를 사용하여 컨테이너 레지스트리에 컨테이너 이미지를 빌드하고 푸시할 수 있습니다:
- 컨테이너 레지스트리에 인증합니다.
-
빌드하거나 푸시하기 위해 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
을 실행하여 방금 빌드한 이미지를 가져옵니다. 이 단계는 특히 이미지를 로컬에 캐시하는 여러 러너를 사용하는 경우에 중요합니다.이미지 태그에 Git SHA를 사용하는 경우, 각 작업은 고유하며 예전 이미지를 가질 가능성이 없습니다. 그러나 의존성이 변경된 후 특정 커밋을 재빌드하는 경우 여전히 예전 이미지를 가질 수 있습니다.
- 여러 작업이 동시에 발생할 수 있으므로
latest
태그로 직접 빌드하지 마세요.
GitLab CI/CD 사용
GitLab CI/CD를 사용하여 컨테이너 이미지를 Container Registry에 빌드하고 푸시할 수 있습니다. CI/CD를 사용하여 생성한 컨테이너 이미지에서 프로젝트를 테스트, 빌드 및 배포할 수 있습니다.
컨테이너 레지스트리에서 Docker-in-Docker 컨테이너 이미지 사용
자신의 컨테이너 이미지를 Docker-in-Docker에 사용할 수 있습니다.
- Docker-in-Docker를 설정합니다.
-
image
와service
를 레지스트리를 가리키도록 업데이트합니다. - 서비스 별칭을 추가합니다.
당신의 .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
Dependency Proxy와 함께하는 Docker-in-Docker 컨테이너 이미지 사용
Dependency Proxy와 함께 자신의 컨테이너 이미지를 사용할 수 있습니다.
- Docker-in-Docker를 설정합니다.
-
image
와service
를 레지스트리를 가리키도록 업데이트합니다. - 서비스 별칭을 추가합니다.
당신의 .gitlab-ci.yml
은 다음과 유사해야 합니다:
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와 함께하는 컨테이너 레지스트리 예제
Docker-in-Docker를 러너에서 사용하는 경우, .gitlab-ci.yml
파일은 다음과 비슷해야 합니다:
build:
image: docker:20.10.16
stage: build
services:
- docker:20.10.16-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:20.10.16
stage: build
services:
- docker:20.10.16-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
는 이 프로젝트에 연결된 레지스트리의 주소로 해석됩니다.
$CI_COMMIT_REF_NAME
은 브랜치 또는 태그 이름으로 해석되며, 슬래시를 포함할 수 있습니다.
이미지 태그는 슬래시를 포함할 수 없습니다.
$CI_COMMIT_REF_SLUG
를 이미지 태그로 사용하세요.
변수 $IMAGE_TAG
를 선언하여 $CI_REGISTRY_IMAGE
와 $CI_COMMIT_REF_NAME
을 조합하여 script
섹션에서 입력을 줄일 수 있습니다.
이 예제는 작업을 4개의 파이프라인 단계로 나누며, 두 개의 테스트가 병렬로 실행됩니다. build
단계는 컨테이너 레지스트리에 저장되며, 이후 단계에서 필요시 컨테이너 이미지를 다운로드합니다. main
에 대한 변경 사항도 latest
로 태그가 지정되고, 애플리케이션 전용 배포 스크립트를 사용하여 배포됩니다:
default:
image: docker:20.10.16
services:
- docker:20.10.16-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/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 실행기를 사용하려는 경우, pull_policy
를 always
로 설정해야 합니다.