도커 레지스트리(Docker Registry) 구축 가이드 - 기본부터 Docker Compose까지

SB신범
7분 읽기
조회수 로딩 중...

Docker Registry 구축 완벽 가이드

Docker Registry는 Docker 이미지를 저장하고 배포할 수 있는 프라이빗 저장소입니다. 공식 Docker Hub를 사용하는 대신 내부 네트워크에서 자체 레지스트리를 운영하면 네트워크 대역폭 절약, 보안 강화, 의존성 관리 등 다양한 이점을 얻을 수 있습니다.

이 가이드에서는 Docker Registry를 구축하는 방법부터 Docker Compose를 활용한 관리 방법까지 상세히 설명합니다.

목차

  1. 환경 준비
  2. Docker Registry 컨테이너 실행하기
  3. 레지스트리 정상 동작 확인
  4. Docker 이미지 올리고 내리기
  5. 원격 접속 설정
  6. 데이터 영구 저장 설정
  7. Docker Compose로 레지스트리 관리하기
  8. CI/CD 파이프라인과 연동하기
  9. 문제 해결 및 팁

1. 환경 준비

Docker Registry를 구축하기 위해서는 다음 요구사항이 필요합니다:

  • 리눅스 서버 (Ubuntu, CentOS, Debian 등)
  • Docker Engine 설치
  • (선택) Docker Compose 설치

Docker 설치

Docker가 설치되지 않은 경우 아래 명령어로 간편하게 설치할 수 있습니다:

bash
1# Docker 설치 2curl -fsSL https://get.docker.com | sh 3 4# Docker 서비스 시작 및 자동 시작 설정 5sudo systemctl start docker 6sudo systemctl enable docker 7 8# 현재 사용자를 docker 그룹에 추가 (sudo 없이 docker 명령어 사용 가능) 9sudo usermod -aG docker $USER

Docker Compose 설치 (선택)

bash
1# Docker Compose 설치 2sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 3 4# 실행 권한 부여 5sudo chmod +x /usr/local/bin/docker-compose 6 7# 설치 확인 8docker-compose --version

2. Docker Registry 컨테이너 실행하기

Docker Hub에서 공식적으로 제공하는 Registry 이미지를 사용하여 간단하게 레지스트리를 실행할 수 있습니다.

bash
1docker run -d -p 5000:5000 --restart=always --name registry registry:2

매개변수 설명:

  • -d: 백그라운드에서 컨테이너 실행
  • -p 5000:5000: 호스트의 5000포트와 컨테이너의 5000포트 연결
  • --restart=always: 시스템 재부팅 시 자동으로 컨테이너 재시작
  • --name registry: 컨테이너 이름 지정
  • registry:2: 사용할 이미지 (공식 Docker Registry v2)

3. 레지스트리 정상 동작 확인

레지스트리가 제대로 작동하는지 확인하려면 API 엔드포인트를 호출해 봅니다:

bash
1curl http://localhost:5000/v2/_catalog

정상 응답 예시:

json
1{"repositories":[]}

빈 저장소 목록이 표시되면 레지스트리가 정상적으로 작동하는 것입니다.


4. Docker 이미지 올리고 내리기

이미지 올리기(Push)

(1) 이미지 태그 지정

레지스트리에 이미지를 올리기 위해서는 먼저 레지스트리 주소를 포함한 태그를 지정해야 합니다:

bash
1docker tag <원본이미지>:<태그> localhost:5000/<새이미지명>:<태그>

예시:

bash
1docker tag nginx:latest localhost:5000/my-nginx:v1

(2) 이미지 업로드(Push)

bash
1docker push localhost:5000/my-nginx:v1

이미지 내려받기(Pull)

다른 시스템이나 같은 시스템에서 레지스트리의 이미지를 사용하려면:

bash
1docker pull localhost:5000/my-nginx:v1

레지스트리에 저장된 이미지 목록 확인

bash
1curl http://localhost:5000/v2/_catalog 2# 결과: {"repositories":["my-nginx"]} 3 4# 특정 이미지의 태그 목록 확인 5curl http://localhost:5000/v2/my-nginx/tags/list 6# 결과: {"name":"my-nginx","tags":["v1"]}

5. 원격 접속 설정

보안 없는 HTTP 접근 허용 (테스트 환경 전용)

실제 운영 환경에서는 권장하지 않지만, 테스트 목적으로 보안 없이 사용하려면:

클라이언트 측 설정:

/etc/docker/daemon.json 파일에 아래 내용 추가:

json
1{ 2 "insecure-registries": ["registry-server-ip:5000"] 3}

설정 적용:

bash
1sudo systemctl restart docker

보안 설정 (운영 환경 권장)

TLS 인증서 설정

  1. 인증서 생성:
bash
1mkdir -p certs 2openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt
  1. 인증서를 사용하여 레지스트리 실행:
bash
1docker run -d -p 5000:5000 --restart=always --name registry \ 2 -v $(pwd)/certs:/certs \ 3 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ 4 -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ 5 registry:2

사용자 인증 추가

기본 인증(Basic Auth) 설정:

bash
1mkdir auth 2docker run --entrypoint htpasswd httpd:2 -Bbn username password > auth/htpasswd 3 4docker run -d -p 5000:5000 --restart=always --name registry \ 5 -v $(pwd)/certs:/certs \ 6 -v $(pwd)/auth:/auth \ 7 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ 8 -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ 9 -e REGISTRY_AUTH=htpasswd \ 10 -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \ 11 -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ 12 registry:2

인증된 레지스트리 접근:

bash
1# 로그인 2docker login registry-server-ip:5000 3 4# 이미지 푸시 5docker push registry-server-ip:5000/my-image:tag

6. 데이터 영구 저장 설정

레지스트리 컨테이너가 삭제되어도 이미지 데이터를 보존하려면 볼륨 마운트가 필수적입니다:

bash
1docker run -d -p 5000:5000 --restart=always --name registry \ 2 -v /docker/registry/data:/var/lib/registry \ 3 registry:2

이렇게 하면 호스트의 /docker/registry/data 디렉토리에 모든 이미지 데이터가 저장됩니다.


7. Docker Compose로 레지스트리 관리하기

Docker Compose를 사용하면 복잡한 설정을 yaml 파일로 관리하고 여러 컨테이너를 쉽게 조율할 수 있습니다.

기본 Docker Compose 설정

docker-compose.yml 파일 생성:

yaml
1services: 2 registry: 3 image: registry:2 4 ports: 5 - "5000:5000" 6 restart: always 7 volumes: 8 - ./registry-data:/var/lib/registry 9 environment: 10 REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry

TLS 및 인증이 적용된 Docker Compose 설정

보안이 강화된 설정의 docker-compose.yml:

yaml
1version: '3' 2 3services: 4 registry: 5 image: registry:2 6 ports: 7 - "5000:5000" 8 restart: always 9 volumes: 10 - ./registry-data:/var/lib/registry 11 - ./certs:/certs 12 - ./auth:/auth 13 environment: 14 REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt 15 REGISTRY_HTTP_TLS_KEY: /certs/domain.key 16 REGISTRY_AUTH: htpasswd 17 REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm 18 REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd 19 # 로깅 설정 추가 20 REGISTRY_LOG_LEVEL: info 21 REGISTRY_LOG_FORMATTER: json 22 23 # UI 추가 (옵션) 24 registry-ui: 25 image: joxit/docker-registry-ui:latest 26 ports: 27 - "8080:80" 28 restart: always 29 environment: 30 - REGISTRY_URL=https://registry:5000 31 - REGISTRY_TITLE=Private Docker Registry 32 - NGINX_PROXY_PASS_URL=https://registry:5000 33 - SINGLE_REGISTRY=true 34 depends_on: 35 - registry

Docker Compose 실행 방법

bash
1# 백그라운드에서 서비스 시작 2docker-compose up -d 3 4# 서비스 상태 확인 5docker-compose ps 6 7# 로그 확인 8docker-compose logs -f 9 10# 서비스 중지 11docker-compose down

Docker Registry UI 추가하기

Docker Registry는 기본적으로 UI를 제공하지 않지만, 서드파티 UI를 사용하여 이미지 관리를 시각화할 수 있습니다:

yaml
1version: '3' 2 3services: 4 registry: 5 # ... 앞서 설정한 레지스트리 설정 ... 6 7 registry-ui: 8 image: joxit/docker-registry-ui:latest 9 ports: 10 - "8080:80" 11 environment: 12 - REGISTRY_URL=http://registry:5000 13 - REGISTRY_TITLE=My Private Registry 14 depends_on: 15 - registry

8. CI/CD 파이프라인과 연동하기

프라이빗 레지스트리는 CI/CD 파이프라인과 연동하여 자동화된 빌드 및 배포 프로세스를 구축할 수 있습니다.

GitHub Actions 예시

.github/workflows/docker-build-push.yml 파일:

yaml
1name: Build and Push 2 3on: 4 push: 5 branches: [ main ] 6 7jobs: 8 build: 9 runs-on: ubuntu-latest 10 steps: 11 - uses: actions/checkout@v3 12 13 - name: Build image 14 run: docker build -t myapp:latest . 15 16 - name: Tag image 17 run: docker tag myapp:latest registry.example.com:5000/myapp:latest 18 19 - name: Login to Registry 20 run: echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login registry.example.com:5000 -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin 21 22 - name: Push image 23 run: docker push registry.example.com:5000/myapp:latest

Gitea Runner 예시

.gitea/workflows/docker-build-push.yml 파일:

yaml
1name: Build and Push 2 3on: 4 push: 5 branches: 6 - main 7 8jobs: 9 build-and-push: 10 runs-on: ubuntu-latest 11 container: 12 image: node:18 13 volumes: 14 - /var/run/docker.sock:/var/run/docker.sock 15 16 steps: 17 - name: 소스코드 체크아웃 18 uses: actions/checkout@v3 19 20 - name: Docker CLI 설치 21 run: | 22 apt-get update 23 apt-get install -y docker.io 24 25 - name: 이미지 빌드 26 run: | 27 docker build -t myapp:${{ github.sha }} . 28 29 - name: 레지스트리 로그인 30 run: | 31 echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login registry.example.com:5000 -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin 32 33 - name: 이미지 태그 및 푸시 34 run: | 35 docker tag myapp:${{ github.sha }} registry.example.com:5000/myapp:${{ github.sha }} 36 docker tag myapp:${{ github.sha }} registry.example.com:5000/myapp:latest 37 docker push registry.example.com:5000/myapp:${{ github.sha }} 38 docker push registry.example.com:5000/myapp:latest

9. 문제 해결 및 팁

일반적인 문제 해결

  1. 오류: 'server gave HTTP response to HTTPS client'

    • 원인: 보안되지 않은 레지스트리에 접근 시 발생
    • 해결: insecure-registries 설정 추가 또는 TLS 인증서 설정
  2. 컨테이너가 시작되지 않는 문제

    bash
    1# 로그 확인 2docker logs registry
  3. 디스크 공간 부족

    bash
    1# 레지스트리 가비지 컬렉션 실행 2docker exec registry registry garbage-collect /etc/docker/registry/config.yml

레지스트리 가비지 컬렉션

오래되거나 사용하지 않는 이미지를 정리하여 디스크 공간을 확보:

bash
1# 가비지 컬렉션 실행 2docker exec registry registry garbage-collect /etc/docker/registry/config.yml

Docker Compose에서:

bash
1docker-compose exec registry registry garbage-collect /etc/docker/registry/config.yml

레지스트리 미러링 설정

Docker Hub 캐싱을 위한 미러 레지스트리 설정:

yaml
1version: '3' 2 3services: 4 mirror-registry: 5 image: registry:2 6 ports: 7 - "5000:5000" 8 environment: 9 REGISTRY_PROXY_REMOTEURL: https://registry-1.docker.io 10 volumes: 11 - ./registry-data:/var/lib/registry 12 restart: always

클라이언트 설정 (/etc/docker/daemon.json):

json
1{ 2 "registry-mirrors": ["http://localhost:5000"] 3}

결론

Docker Registry는 개인 또는 조직의 이미지 관리를 위한 필수 도구입니다. 이 가이드를 통해 기본적인 설정부터 Docker Compose를 활용한 고급 설정, 그리고 CI/CD 파이프라인과의 연동까지 다양한 방법을 살펴보았습니다.

보안 설정과 주기적인 유지보수는 레지스트리 운영에 있어 매우 중요하므로, 운영 환경에서는 반드시 TLS와 인증을 설정하고 정기적으로 가비지 컬렉션을 실행할 것을 권장합니다.

더 자세한 정보는 Docker Registry 공식 문서를 참조하세요.