- Unregistry는 Docker 데몬 저장소에서 이미지를 직접 저장·제공하는 경량 컨테이너 이미지 레지스트리이며,
docker pussh 명령으로 원격 Docker 서버에 이미지를 SSH로 바로 전송함
- 기존 선택지는 Docker Hub/GitHub Container Registry, 자체 호스팅 레지스트리,
docker save | ssh... docker load, 원격 재빌드인데, 각각 공개·유료 저장소, 운영 부담, 전체 이미지 전송, 서버 자원 낭비 문제가 있음
docker pussh myapp:latest user@server는 SSH 터널을 만들고 원격 서버에서 임시 unregistry 컨테이너를 띄운 뒤, 포워딩된 localhost 포트로 docker push를 수행해 원격에 없는 레이어만 전송함
- 원격 서버에는 Docker 실행 환경,
docker 명령 권한, 최초 실행 시 ghcr.io/psviderski/unregistry:latest 접근이 필요하며, unregistry 컨테이너는 /run/containerd/containerd.sock 접근 때문에 root로 실행됨
- Docker의 containerd image store를 활성화하면 전송된 이미지가 Docker에서 즉시 사용 가능하고 중복 저장을 피할 수 있지만, 기존 classic storage driver로 만든 이미지와 컨테이너가 일시적으로 보이지 않을 수 있음
Unregistry가 해결하는 배포 문제
- Unregistry는 외부 레지스트리 없이 Docker 이미지를 원격 서버로 옮기기 위한 경량 컨테이너 이미지 레지스트리임
- 포함된 Docker CLI 플러그인 명령은
docker pussh이며, 이름의 추가 s는 SSH를 뜻함
- 로컬에서 만든 Docker 이미지를 서버로 옮길 때 일반적인 선택지는 다음과 같은 제약이 있음
- Docker Hub / GitHub Container Registry: 코드가 공개되거나 private 저장소 비용을 부담해야 함
- Self-hosted registry: 유지보수, 보안, 저장소 비용이 필요한 별도 서비스가 생김
- Save/Load:
docker save | ssh <remote server> docker load는 서버에 이미 90%가 있어도 전체 이미지를 전송함
- Remote rebuild: 시간과 서버 자원을 쓰며, 프로덕션에서 빌드 실패 원인을 디버깅해야 할 수 있음
docker pussh 동작 방식
docker pussh myapp:latest user@server
- 이 명령은 레지스트리 설정, 구독, 중간 저장소, 공개 포트 없이 누락된 레이어만 SSH로 직접 전송함
- 내부 동작은 다음 순서로 진행됨
- 원격 서버로 SSH 터널을 생성함
- 서버에서 임시 unregistry 컨테이너를 시작함
- 임의의 localhost 포트를 터널을 통해 unregistry 포트로 포워딩함
- 포워딩된 포트로
docker push를 수행해 원격에 없는 레이어만 전송함
- 전송된 이미지는 원격 Docker 데몬에서 즉시 사용 가능함
- unregistry 컨테이너를 중지하고 SSH 터널을 닫음
- 프로젝트는 Docker 이미지를 위한
rsync 같은 방식으로 단순하고 효율적인 전송을 목표로 함
- Unregistry는 여러 Docker 호스트에 컨테이너를 배포하는 경량 도구 Uncloud를 위해 만들어졌으며, 전체 레지스트리보다 단순하고 save/load보다 효율적인 방식이 필요했음
실행 요구사항과 제약
- 로컬 머신에는 Docker CLI 플러그인 지원이 필요하며, Docker 19.03 이상과 OpenSSH 클라이언트가 필요함
- 원격 서버에는 Docker가 설치되어 실행 중이어야 함
- SSH 사용자는
docker 명령을 실행할 권한이 있어야 함
- 최초
docker pussh 실행 시 원격 서버가 ghcr.io에서 ghcr.io/psviderski/unregistry:latest 이미지를 가져올 수 있어야 함
- 프록시가 필요한 서버는 Docker의 Daemon proxy configuration 안내에 따라 설정해야 함
- air-gapped 환경이나
ghcr.io 접근이 제한된 환경에서는 필요한 unregistry 이미지 버전을 확인한 뒤 수동으로 preload할 수 있음
- unregistry 컨테이너는
/run/containerd/containerd.sock에 접근해야 하므로 필요한 권한을 위해 root로 실행됨
설치와 지원 플랫폼
- macOS/Linux에서는 Homebrew로
docker-pussh를 설치할 수 있음
brew install psviderski/tap/docker-pussh
- Homebrew 설치 후 Docker CLI 플러그인으로
docker pussh를 쓰려면 ~/.docker/cli-plugins/docker-pussh 심볼릭 링크를 만들어야 함
- macOS/Linux에서는 직접 다운로드 방식도 제공됨
- 현재 버전 예시는
v0.4.3의 docker-pussh 스크립트를 Docker 플러그인 디렉터리에 내려받아 실행 권한을 부여하는 방식임
- main 브랜치의 최신 스크립트를 내려받는 방식도 제공됨
- Debian은 @dariogriffo가 만들고 관리하는 비공식 패키지 저장소 unregistry-debian을 통해 설치할 수 있음
- Windows는 현재 지원되지 않지만, WSL 2와 Linux 설치 절차를 시도할 수 있음
- 설치 확인은 다음 명령으로 수행함
docker pussh --help
containerd image store 설정
사용 예시
- 기본 전송은 이미지 이름과 원격 SSH 대상만 지정함
docker pussh myapp:latest user@server.example.com
- SSH agent에 private key가 등록되지 않은 경우
-i로 키를 지정할 수 있음
docker pussh myapp:latest ubuntu@192.168.1.100 -i ~/.ssh/id_rsa
- 커스텀 SSH 포트는 대상 뒤에 포트를 붙여 지정함
docker pussh myapp:latest user@server:2222
- 커스텀 SSH config 파일은
-F로 지정함
docker pussh myapp:latest prod-server -F ~/.ssh/config.prod
- 멀티 플랫폼 이미지에서 특정 플랫폼만 push하려면
--platform을 사용함
docker pussh myapp:latest user@server --platform linux/amd64
- 원격 호스트에서 특정 unregistry 이미지 버전을 쓰려면
UNREGISTRY_IMAGE 환경 변수를 지정함
UNREGISTRY_IMAGE=ghcr.io/psviderski/unregistry:A.B.C docker pussh myapp:latest user@server.example.com
대표 사용 사례
- 프로덕션 서버 배포에서는 로컬에서 빌드한 이미지를 중간 레지스트리 없이 서버로 직접 push하고 실행할 수 있음
docker build --platform linux/amd64 -t myapp:1.2.3 .
docker pussh myapp:1.2.3 deploy@prod-server
ssh deploy@prod-server docker run -d myapp:1.2.3
- CI/CD 파이프라인에서는 레지스트리 복잡성을 건너뛰고 배포 대상에 직접 이미지를 보낼 수 있음
- name: Build and deploy
run: |
docker build -t myapp:${{ github.sha }} .
docker pussh myapp:${{ github.sha }} deploy@staging-server
- homelab과 air-gapped 환경에서는 공용 레지스트리에 인터넷으로 접근할 수 없는 격리 네트워크에서 이미지를 배포할 수 있음
고급 사용과 관련 프로젝트
- Unregistry는 독립 실행형 로컬 레지스트리로도 사용할 수 있음
/run/containerd/containerd.sock을 마운트하고 ghcr.io/psviderski/unregistry 컨테이너를 실행함
- 이후
localhost:5000을 일반 레지스트리처럼 docker tag와 docker push에 사용할 수 있음
- SSH 설정은 표준 SSH config 파일을 쓰거나
-F로 별도 config 파일을 전달할 수 있음
- 관련 서드파티 프로젝트가 제공됨
- 구현에는 Spegel과 Docker Distribution이 언급됨
- Spegel은 containerd image store를 백엔드로 쓰는 레지스트리 구현에 영감을 준 P2P 컨테이너 이미지 레지스트리임
- Docker Distribution은 unregistry의 기반이 된 Docker registry 구현임