- Unregistry एक हल्की container image registry है, जो Docker daemon storage से सीधे images को store और serve करती है, और
docker pussh command के जरिए images को SSH से सीधे remote Docker server पर भेजती है
- मौजूदा विकल्प Docker Hub/GitHub Container Registry, self-hosted registry,
docker save | ssh... docker load, और remote rebuild हैं; इनमें क्रमशः public/paid repository, operations का बोझ, पूरी image transfer, और server resources की बर्बादी जैसी समस्याएं हैं
docker pussh myapp:latest user@server SSH tunnel बनाता है, remote server पर अस्थायी unregistry container चलाता है, फिर forwarded localhost port पर docker push करता है ताकि केवल वे layers भेजे जाएं जो remote पर मौजूद नहीं हैं
- remote server पर Docker runtime environment,
docker command की permission, और पहली बार चलाने पर ghcr.io/psviderski/unregistry:latest तक access जरूरी है; unregistry container /run/containerd/containerd.sock access की वजह से root के रूप में चलता है
- Docker का containerd image store enable करने पर भेजी गई image Docker में तुरंत इस्तेमाल हो सकती है और duplicate storage से बचा जा सकता है, लेकिन classic storage driver से बनाई गई मौजूदा images और containers अस्थायी रूप से दिखाई नहीं दे सकते
Unregistry जिस deployment समस्या को हल करता है
- Unregistry बाहरी registry के बिना Docker images को remote server पर ले जाने के लिए एक हल्की container image registry है
- इसमें शामिल Docker CLI plugin command
docker pussh है, और नाम में अतिरिक्त s SSH को दर्शाता है
- local पर बनाई गई Docker image को server पर ले जाते समय आम विकल्पों में ये सीमाएं हैं
- Docker Hub / GitHub Container Registry: code public हो सकता है या private repository की cost देनी पड़ती है
- Self-hosted registry: maintenance, security और storage cost वाला अलग service बन जाता है
- Save/Load:
docker save | ssh <remote server> docker load server पर पहले से 90% मौजूद होने पर भी पूरी image transfer करता है
- Remote rebuild: समय और server resources खर्च होते हैं, और production में build failure की वजह debug करनी पड़ सकती है
docker pussh कैसे काम करता है
- basic usage की एक line यह है
docker pussh myapp:latest user@server
- यह command registry setup, subscription, intermediate storage या public port के बिना सिर्फ missing layers को सीधे SSH से transfer करती है
- internal flow इस क्रम में चलता है
- remote server तक SSH tunnel बनाता है
- server पर temporary unregistry container start करता है
- किसी arbitrary localhost port को tunnel के जरिए unregistry port पर forward करता है
- forwarded port पर
docker push करके remote पर न मौजूद layers ही transfer करता है
- transfer की गई image remote Docker daemon में तुरंत इस्तेमाल के लिए उपलब्ध होती है
- unregistry container रोकता है और SSH tunnel बंद करता है
- project का लक्ष्य Docker images के लिए
rsync जैसी सरल और efficient transfer विधि देना है
- Unregistry को कई Docker hosts पर containers deploy करने वाले lightweight tool Uncloud के लिए बनाया गया था, जहां full registry से सरल और save/load से ज्यादा efficient तरीका चाहिए था
चलाने की requirements और limitations
- local machine पर Docker CLI plugin support चाहिए, साथ ही Docker 19.03 या उससे ऊपर और OpenSSH client चाहिए
- remote server पर Docker installed और running होना चाहिए
- SSH user के पास
docker command चलाने की permission होनी चाहिए
- user
root हो या non-root user docker group में हो
- संबंधित documentation के लिए Docker का Manage Docker as a non-root user देखें
- अगर
sudo जरूरी है, तो password prompt के बिना sudo docker चला पाना चाहिए
- पहली बार
docker pussh चलाते समय remote server को ghcr.io से ghcr.io/psviderski/unregistry:latest image pull कर पाने की जरूरत होती है
- जिन servers को proxy चाहिए, उन्हें Docker के Daemon proxy configuration guide के अनुसार configure करना होगा
- air-gapped environment या
ghcr.io access restricted environment में जरूरी unregistry image version की जांच करके manual preload किया जा सकता है
- unregistry container को
/run/containerd/containerd.sock तक access चाहिए, इसलिए जरूरी permissions के लिए यह root के रूप में चलता है
installation और supported platforms
- macOS/Linux पर Homebrew से
docker-pussh install किया जा सकता है
brew install psviderski/tap/docker-pussh
- Homebrew installation के बाद Docker CLI plugin के रूप में
docker pussh इस्तेमाल करने के लिए ~/.docker/cli-plugins/docker-pussh symbolic link बनाना होगा
- macOS/Linux पर direct download method भी उपलब्ध है
- current version example में
v0.4.3 का docker-pussh script Docker plugin directory में download करके execute permission दी जाती है
- main branch का latest script download करने का तरीका भी दिया गया है
- Debian को @dariogriffo द्वारा बनाए और maintain किए गए unofficial package repository unregistry-debian के जरिए install किया जा सकता है
- Windows फिलहाल supported नहीं है, लेकिन WSL 2 और Linux installation procedure आजमाया जा सकता है
- installation verify करने के लिए यह command चलाएं
docker pussh --help
containerd image store configuration
usage examples
- basic transfer में सिर्फ image name और remote SSH target specify किया जाता है
docker pussh myapp:latest user@server.example.com
- अगर private key SSH agent में registered नहीं है, तो
-i से key specify की जा सकती है
docker pussh myapp:latest ubuntu@192.168.1.100 -i ~/.ssh/id_rsa
- custom SSH port target के बाद port जोड़कर specify किया जाता है
docker pussh myapp:latest user@server:2222
- custom SSH config file
-F से specify की जाती है
docker pussh myapp:latest prod-server -F ~/.ssh/config.prod
- multi-platform image में सिर्फ किसी specific platform को push करना हो तो
--platform इस्तेमाल करें
docker pussh myapp:latest user@server --platform linux/amd64
- remote host पर किसी specific unregistry image version का उपयोग करने के लिए
UNREGISTRY_IMAGE environment variable specify करें
UNREGISTRY_IMAGE=ghcr.io/psviderski/unregistry:A.B.C docker pussh myapp:latest user@server.example.com
प्रमुख use cases
- production server deployment में local पर build की गई image को intermediate registry के बिना सीधे server पर 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 pipeline में registry complexity को skip करके image को सीधे deployment target पर भेजा जा सकता है
- name: Build and deploy
run: |
docker build -t myapp:${{ github.sha }} .
docker pussh myapp:${{ github.sha }} deploy@staging-server
- homelab और air-gapped environments में public registry तक internet access न रखने वाले isolated networks में images deploy की जा सकती हैं
advanced usage और related projects
- Unregistry को standalone local registry के रूप में भी इस्तेमाल किया जा सकता है
/run/containerd/containerd.sock को mount करके ghcr.io/psviderski/unregistry container चलाएं
- इसके बाद
localhost:5000 को normal registry की तरह docker tag और docker push में इस्तेमाल किया जा सकता है
- SSH configuration standard SSH config file से किया जा सकता है, या
-F से अलग config file pass की जा सकती है
- related third-party projects उपलब्ध हैं
- implementation में Spegel और Docker Distribution का उल्लेख है
- Spegel एक P2P container image registry है जिसने containerd image store को backend के रूप में इस्तेमाल करने वाली registry implementation के लिए inspiration दी
- Docker Distribution वह Docker registry implementation है जिस पर unregistry आधारित है
1 टिप्पणियां
Hacker News की रायें
Docker बनाने वाले के नज़रिए से यह पसंद आया। आदर्श design शायद ऐसा single server होता जिसमें Docker engine और registry का कोई अलगाव नहीं होता
अगर ज़रूरत के हिसाब से containers को store, transfer और run किया जा सकता, तो यह कहीं ज़्यादा मजबूत component बनता, और engine व registry के image store करने के तरीकों में जो उलझा हुआ divergence है, उससे भी बचा जा सकता था
साथ ही, मेरा मानना है कि हर production cluster में distributed image store होना चाहिए, और उस store में image push करना ही deployment trigger करना चाहिए था। आज की तरह registry में push करना, cluster configure करना, और फिर हर node का registry से pull करना—यह fragile और inefficient है। मैंने बेहतर design के लिए दलील दी थी, लेकिन inertia तब तक बहुत बड़ा हो चुका था, और शुरुआती Kubernetes community Docker से आए ideas के प्रति hostile थी
cluster में push करके deployment smart लगता है। सभी nodes पर unregistry डालकर उन्हें एक-दूसरे से images fetch और share करने देने जैसा distributed image store मैं सोच रहा हूं, लेकिन push से deployment trigger करने वाले तरीके पर थोड़ा और विचार करना होगा
अच्छा है।
pusshcommand सचमुच elegant pun के तौर पर मान्यता पाने लायक है। याद रखने में आसान, मतलब तुरंत साफ, और अपनी sibling standard command से सिर्फ एक अक्षर अलगdocker push-over-sshजैसा कोई ज़्यादा official alias भी हो तो अच्छा होगाcollaborative automation में,
pusshउस व्यक्ति को typo जैसा लग सकता है जिसे feature पता न हो, जिससे अनावश्यक confusion हो सकता है। इसके उलटpush-over-sshसे साफ है कि यह intended name है। इसे short option और long option की तरह समझेंs,ssshवालाsहै“वह extra
sक्या है?”“typo है”
2015 में मैंने naive होकर इस feature को Docker mainline में डालने के लिए PR[1] भेजा था, लेकिन जल्दी ही मुझे दूसरे areas में मदद करने की तरफ मोड़ दिया गया। registry के बिना काम चलाने देना शायद Docker के business model को बहुत हिला देता
[1]: https://github.com/richardcrichardc/docker2docker
आखिरकार योजना शायद default को containerd image store पर switch करने की होगी। local और remote दोनों जगह containerd image store इस्तेमाल होने लगे तो registry wrapper के बिना भी वही किया जा सकेगा जो मूल implementation में था
यह Ansible जैसे push deployment tools पहले से इस्तेमाल करने वाले systems के साथ अच्छी तरह fit होने वाला शानदार idea लगता है। जिन companies के पास Docker registry के लिए 24/7 support नहीं है, उनके लिए यह अच्छा hotfix deployment mechanism भी हो सकता है
जिज्ञासा है कि क्या यह buildah जैसे OCI tools के साथ साफ-सुथरे तरीके से integrate होता है, या दोनों सिरों पर पूरा Docker install चाहिए। अभी गहराई से नहीं देखा, लेकिन ऐसे setup में skopeo को चलाने के लिए remote server पर mini registry bootstrap करना missing piece जैसा लगता है
Unregistry API layer में official Docker registry code reuse करता है, इसलिए यह https://hub.docker.com/_/registry जैसा दिखता और behave करता है
client पर skopeo, crane, regclient, BuildKit जैसे OCI registry बोलने वाले tools इस्तेमाल कर सकते हैं। बस इन्हें इस्तेमाल करने के लिए remote host पर unregistry manually run करना होगा।
docker pusshcommand केवल local Docker का इस्तेमाल करके इस flow को automate करती हैइसे बस Bash script समझें: https://github.com/psviderski/unregistry/blob/main/docker-pu...
आप इसे अपने मनचाहे तरीके से आसानी से बदल सकते हैं
शुरू से यही होना चाहिए था। बेहतरीन
Docker registry की अपनी जगह है, लेकिन कुल मिलाकर वह over-engineered है और hacker spirit के उलट तरफ है
private ghcr.io registry में images build और push करने वाला
.yamlworkflow setup करने में 20 मिनट, और server को वहां से images fetch करने की permission देने में करीब 5 मिनट लगे। काफी practical setup हैमैं एक pipeline देख रहा हूं जिसमें GitLab में image build होती है और Artifactory में push होती है, फिर deployment trigger होकर Artifactory से pull करता है और AWS ECR में फिर push करता है, EKS के deployment template को update करता है, फिर ECR से nodes पर pull करके Pod container चलाता है
मेरी जिंदगी में मुझे इसकी ज़रूरत है
इसे देखकर मुझे uncloud के बारे में पता चला। मैं side project server setup के लिए dokku जैसा, लेकिन थोड़ा ज्यादा powerful कुछ खोज रहा था, और यह बिल्कुल वैसा ही लगता है
इसका stack feature भी सच में अच्छा है; असल में यह Docker Compose ही है। एक EC2 instance पर Portainer Agent container के अंदर Caddy चलाता है, और Caddy load balancer और reverse proxy की भूमिका निभाता है
यह काफी अजीब है कि Docker शुरू से ही ऐसे काम नहीं करता था। शानदार लगता है
archive save करना
docker save -o may-app.tar my-app:latestकी तरह, और load करनाdocker load -i /path/to/my-app.tarकी तरह होता हैAnsible जैसे tools का इस्तेमाल करके “Unregistry” जो automate करता है, उसे आसानी से हासिल किया जा सकता है। GitHub repository के मुताबिक save/load approach की कमी यह है कि इसमें पूरी image network पर भेजी जाती है, और यह सच में समस्या बन सकता है। archive file के बजाय image को ही manage करना भी ज्यादा convenient लगता है
साफ-सुथरा project और approach है। महंगी registries से परेशान होकर मैंने Zot[1] को self-host करना शुरू किया, लेकिन कुछ use cases में यह काफी ज्यादा आसान लगता है
मुझे जिज्ञासा है कि क्या और लोगों को भी ऐसा लगता है कि कोई private registry service होनी चाहिए जो आसानी से setup हो सके, सस्ती हो, और usage-based billing वाली हो
[1]: https://zotregistry.dev
अच्छा idea है। हालांकि deployment के service से tightly coupled हो जाने की कमी हो सकती है। उदाहरण के लिए, scale out या red/green deployment कैसे करेंगे, यह साफ नहीं है, और लगता है कि जो हिस्सा यह काम करता है उसे push के बारे में पता होना चाहिए
edit: वही काम uncloud कर रहा था। अभी-अभी पता चला
फिर भी यह trade-off है। अगर scale छोटा है, आप एक Hetzner VM इस्तेमाल कर रहे हैं, simplicity से संतुष्ट हैं, और local पर image build करना भी ठीक है, तो यह शानदार है