Docker Private Registry

김민기·2025년 5월 10일
0

Docker Image Registry

Dockerfile을 사용해서 도커 이미지를 만들고
다른 사용자도 이미지를 사용할 수 있게 하려면 이미지를 어딘가에 업로드해야 한다.

이때 주로 사용하는 레지스트리로는 다음과 같은 2가지가 존재한다.

  1. 도커 허브
  2. AWS ECR

ECR의 경우 AWS EC2, S3와 같이 AWS 에서 제공하는 다른 서비스와 연계하기 쉽다는 장점이 있고
도커 허브의 경우 기본적으로 없는 이미지를 받아오려고 할 때 가장 먼저 찾아보는 곳으로 많은 사람들이 사용한다는 장점이 있다. 그러나 도커 허브의 경우 1개의 레포지토리만 private으로 설정할 수 있으며 그 이상부터는 요금을 지불해야 하고 ECR은 private으로 여러개의 이미지를 올릴 수 있지만 이미지 용량에 따라 요금을 지불해야 한다.

나는 간단하게 도커 이미지를 사용해서 협업중인 디자이너에게 개발중인 Next.js 프론트 애플리케이션을 전달하고 싶었다.
동일한 네트워크(회사)에 접속한 상태에서 내 IP 주소를 알려주고 직접 들어와서 현재 디자인이 어떻게 적용되고 있는지를 공유하고 있었는데, 개발중인 상황에서 내가 소스코드를 수정하는 동안 페이지에 에러가 발생하거나 다른 문제가 발생한다면 디자이너는 화면을 볼 수 없는 문제가 있었고, 내 PC를 항상 켜놔야 하는 문제가 있었다.(휴가 기간동안 PC를 끄지 못하거나 끄고 갔을 경우 공유할 수 없는 문제)

따라서 도커로 이미지를 만들어서 디자이너 PC에서 실행하도록 한다면
굳이 내 PC와 관계없이 충분히 공유할 수 있을 것이라 생각했다.

물론, 실시간으로 변경사항이 적용되지는 않지만 그 부분이 크게 문제가 되지 않았다.

본격적인 문제는 도커 이미지를 어떻게 공유할 것인가 였는데
도커 허브, ECR 을 사용하기에는 너무 오버 스펙이 아닌가 싶어서 다른 방법을 찾아보던 중
Private Registry를 만드는 방법을 알게되었고
간단하게 이미지를 공유하는 방법으로는 최적이라는 생각이 들어서 마침 회사에 남는 윈도우 노트북으로 Private Registry를 만들었다.

Private Registry 만들기

포스팅하는데 정말 많은 도움을 받은 참고 사이트
💯 ✏️ https://kkjsw17.tistory.com/9

목표

Private Registry + GUI
레지스트리를 구축하면서 이걸 GUI로 확인할 수 있는 방법도 만들어본다.

✅ Windows OS에서 작업했습니다 (Powershell)

필요한 이미지 준비하기

docker image pull registry:2
docker image pull hyper/docker-registry-web

첫 번째 이미지는 레지스트리를 구축하는데 사용하고
두 번째 이미지는 레지스트리의 GUI 구축용

docker network 생성

docker network create registry

✅ 레지스트리의 GUI가 필요하지 않다면 네트워크를 만들필요는 없다. 레지스트리와 GUI를 같은 네트워크를 공유할 수 있도록 하기 위해서 필요한 설정

Volume 디렉터리 생성

mkdir -p /data/docker/auth [Linux]
mkdir -Force /data/docker/auth [Windows]

✅ 파일 경로 주의

Private 레지스트리이기 때문에 당연히 아무나 접근할 수는 없어야 한다.
따라서 레지스트리에 접근할 수 있는 인증 관련 정보를 저장해두고 있어야 함.

인증 파일 관련 이슈 (htpasswd)

참고한 블로그에서도 나와 있지만 registry:2 이미지에서는 보안상의 이유로 2020년경부터 htpasswd 명령어를 삭제했다고 한다. 따라서 다른 방법을 제시하고 있는데 로컬에 직접 설치하는 그 방법보다는 나는 httpd:2.4 이미지를 사용하는 방법을 사용했다.

실패한 방법

docker run --rm httpd:2.4 htpasswd -Bbn 사용자명 비밀번호 > C:\data\docker\auth\htpasswd

이 명령어로 실행하면 만들어진 htpasswd을 사용해서 나중에 도커 로그인을 하려고 할 때 에러가 발생한다.
htpasswd: invalid entry at line 2: "\x00\r\x00" 로그에 다음과 같은 에러가 보이는데
GPT에게 물어봤을 때 여러가지 가능성을 설명해줬는데, 결과적으로는 인코딩 오류로 보인다.
따라서 굳이 복잡하게 다른 해결방법을 찾기보다 간단한 방법으로 대체한다.

성공한 방법

docker run --rm -v C:\data\docker\auth:/auth `
	httpd:2.4 htpasswd -Bbc /auth/htpasswd user 1234

이 명령어는 쉽게 말해서 컨테이너에서 htpasswd 파일을 만들고 호스트로 복사해온다. 따라서 인코딩 문제 없이 htpasswd 파일을 만들 수 있게된다.
사용자 이름은 user 패스워드는 1234로 설정했다.

Registry 실행

docker run -d `
	--restart=always`
	--name registry `
	--network registry `
	-v C:\data\docker\auth:/auth `
	-v C:\data\docker\registry:/var/lib/registry `
	-e "REGISTRY_AUTH=htpasswd" `
	-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" `
	-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" `
	-p 5000:5000 `
	registry: 2

인증 정보가 들어 있는 C:\data\docker\auth 경로와 컨테이너의 /auth 경로를 매칭한다.
그리고 C:\data\docker\registry 경로의 경우 생성한적이 없기 때문에 컨테이너에서 생성한 /var/lib/registry 경로에 위치한 파일을 C:\data\docker\registry 폴더로 이동시킨다. (없을 경우 자동 생성)
나머지는 환경변수를 전달하는 내용이고 5000번 포트를 사용한다.

도커 데스크탑 설정

도커 데스크탑을 사용하고 있다면 5000번 포트를 Https 가 아닌 Http로 가져올 수 있게 하기 위해서
Docker Desktop -> settings -> Docker Engine 메뉴를 직접 수정한다.

{
	"insecure-registries": ["192.168.0.23:5000"], // IP 주소에 맞게 수정
    ...(다른 설정들)
}

필요에 따라 localhost:5000을 추가해야 할 수도 있다.

Image Push

이미지를 Push 하기 전에 레지스트리에 접근할 수 있는 권한을 획득해야 한다.

docker login localhost:5000

명령어를 입력하면 user, password를 입력하라고 나오는데, 이전에 인증파일을 만들었을 때 사용한 유저 이름과 비밀번호를 입력하면 된다.

💡 주의할 점으로 지금 PC는 레지스트리를 구축하고 있는 PC 이기 때문에 localhost를 사용한다. 만약 레지스트리를 구축하고 있는 PC의 IP 주소가 192.168.0.23 일 경우 같은 네트워크 환경에 있는 다른 PC에서 접속할 때는 192.168.0.23:5000 으로 접근해야 한다.

인증 권한이 있는 상태에서 정상적으로 이미지가 푸시되는지 확인하기 위해서 이미지를 하나 받아와서 태그를 달고 레지스트리에 푸시해본다.

docker pull busybox
docker tag busybox 192.168.0.23:5000/busybox

docker push 192.168.0.23:5000/busybox

아직 GUI를 구축하기 전 임으로 이미지가 정상적으로 푸시되었는지 확인하기 위해

curl -u user:1234 http://192.168.0.23/v2/_catalog

명령어를 입력해본다.

Image Pull

이미지를 가져오고 싶은 곳에서 레지스트리에 접근하기 위해 로그인을 먼저 실행한다.

docker login 192.168.0.23:5000
docker pull 192.168.0.23:5000/busybox

이미지를 가져와서 docker run 또는 컴포즈 파일을 만들어서 docker-compose up을 실행하면 된다.

GUI 연결하기

GUI를 연결하는 방법은 간단하다
이전에 설치한 이미지가 있기 때문에 다음과 같이 이미지를 실행한다.

docker run -d `
	-p 8080:8080
	--name registry-web `
	--network registry `
	-e REGISTRY_URL=http://registry:5000/v2 `
	-e REGISTRY_NAME=localhost:5000 `
	-e REGISTRY_BASIC_AUTH="dXNlcjoxMjM0" ` // "user:1234"를 Base64로 인코딩
	--restart=always `
	hyper/docker-registry-web

8080번 포트를 사용하기 때문에 localhost:8080으로 접속하면 GUI로 업로드 되어 있는 도커 이미지를 확인할 수 있다.

실제로 공유해보기

다음과 같은 상황을 가정한다.

회사의 1대의 PC에 Private Registry를 구축한다. (GUI는 옵션)
같은 네트워크 환경에서

  1. A라는 개발자가 이미지를 빌드하고 레지스트리에 Push 한다.
  2. B라는 디자이너가 레지스트리에 접근해서 이미지를 가져와서 컨테이너를 실행한다.

A - 개발자 (공유자)

필요한 것?

  1. 도커 데스크탑에서 insecure-registries 설정하기
  2. 레지스트리 접근 권한 얻기
  docker login 192.168.0.23:5000
  1. 도커 빌드 후 이미지 push
 docker build --platform linux/amd64 -t 192.168.0.23:5000/my-next-app-dev .
 docker push 192.168.0.23:5000/my-next-app-dev

💡 Mac에서 빌드한 이미지를 Linux/WSL 기반 Windows에서 실행할 때,
기본적으로 Mac은 ARM64 플랫폼이기 떄문에
Windows의 linux/amd64 플랫폼에서 컨테이너 실행 시 아키텍처 mismatch가 발생할 수 있음
따라서 반드시
docker build --platform linux/amd64 -t my-image . 이런 식으로 빌드해줘야 함.
없이 하면 Windows 도커에서 실행안되는거 확인…

B - 디자이너 (받는 사람)

필요한 것?

  1. 도커 데스크탑에서 insecure-registries 설정하기
  2. 레지스트리 접근 권한 얻기
 docker login 192.168.0.23:5000
  1. 도커 이미지 다운로드 후 docker-compose로 실행하기
 docker login 192.168.0.23:5000
 docker pull 192.168.0.23:5000/my-next-app-dev
 docker-compose up
  1. docker-compose.yml 파일을 만들고 실행한다.

이때 도커 컴포즈를 사용하면 좋은게 포트 번호를 (80:3000) 으로 사용했고 (docker run으로도 가능하지만 길어지니까 귀찮아…) 그리고 env 파일도 있기 때문에 컴포즈로 작성하면 좋다.

이 방법을 사용해서 얻은 장점으로

  1. 이미지를 수시로 업데이트하지 않기 때문에 필요할 때 간단하게 이미지를 공유할 수 있는 레지스트리 환경을 무료로 구축할 수 있었음.
  2. 단순히 디자이너와의 공유 뿐만아니라 QA에도 도움이 될 수 있는 환경 구축 가능.

그러나 단점으로는
도커 허브나, ECR을 대체하기 위해서는 예를 들어 Github Action에서 도커 이미지를 만들어서 Private Registry에 Push 할 수 있도록 만들어야 하는데, 이를 위해서 SSL 인증이 필요하고 추가적으로 다른 네트워크 (회사 내부를 벗어난 네트워크) 환경으로 넓어진다면 보안위험성이 증가할 수 있다는 점

따라서 간단하게 내부적으로 이미지 공유하는데 있어서는 정말 좋은 장점이 될 수 있지만 도커 허브와 ECR을 완벽하게 대체하기에는 어려움이 있을것이라 생각된다.

0개의 댓글