SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-09-04

Rocky Linux और AlmaLinux पर Docker कैसे इंस्टॉल करें

Rocky Linux या AlmaLinux पर Docker Engine इंस्टॉल करने का सही तरीका जानें। हम dnf रिपॉजिटरी सेटअप, Podman के साथ संघर्ष और SELinux bind mounts जैसी समस्याओं का समाधान देंगे।

Rocky Linux और AlmaLinux पर Docker इंस्टॉल करना

Rocky Linux या AlmaLinux पर Docker इंस्टॉल करने के लिए आप Docker की अपनी dnf रिपॉजिटरी जोड़ते हैं, compose प्लगइन के साथ इंजन इंस्टॉल करते हैं, और फिर सर्विस को इनेबल करते हैं। यह प्रक्रिया चार कमांड्स की है, और दोनों डिस्ट्रिब्यूशन पर एक समान है क्योंकि दोनों Red Hat Enterprise Linux (RHEL) के रीबिल्ड हैं और एक ही पैकेज लेआउट साझा करते हैं। CentOS Stream भी इसी तरह काम करता है। नीचे दी गई हर बात दोनों पर लागू होती है, इसलिए यदि आप अभी भी उनके बीच चयन कर रहे हैं, तो निर्णायक कारक प्रत्येक प्रोजेक्ट द्वारा किया गया संगतता का वादा और यह है कि क्या आपका पुराना CPU अभी भी समर्थित है।

इंस्टॉलेशन छोटा है, इसलिए इस गाइड का अधिकांश हिस्सा यह बताता है कि Enterprise Linux (EL) Ubuntu से अलग क्या करता है। Podman आपके इमेज पर पहले से ही docker कमांड का उपयोग कर सकता है। SELinux तब तक bind-mounted फाइलों को ब्लॉक करता है जब तक कि उन पर सही लेबल न हो। Firewalld Docker के पब्लिश किए गए पोर्ट्स को फ़िल्टर नहीं करता है, इसलिए एक कंटेनर पोर्ट इंटरनेट के लिए खुला हो सकता है जबकि firewall-cmd रिपोर्ट करता है कि कुछ भी खुला नहीं है।

get.docker.com से Docker की सुविधा स्क्रिप्ट (convenience script) का उपयोग न करें। Docker का अपना दस्तावेज़ कहता है कि यह प्रोडक्शन के लिए अनुशंसित नहीं है। यह बिना पूछे आपकी रिपॉजिटरी कॉन्फ़िगरेशन को फिर से लिख देता है, और इसे अपग्रेड करने के लिए सुरक्षित रूप से दोबारा नहीं चलाया जा सकता है। रिपॉजिटरी को मैन्युअल रूप से जोड़ने का मतलब है कि dnf upgrade Docker को बॉक्स पर मौजूद हर दूसरे पैकेज की तरह ही मानता है। यह इंजन को dnf-automatic, यदि आप इसे टाइमर पर सुरक्षा अपडेट लागू करने के लिए उपयोग करते हैं के दायरे में भी लाता है, इसलिए जल्दी निर्णय लें कि क्या आप चाहते हैं कि Docker को बिना निगरानी के पैच किया जाए या रखरखाव विंडो के लिए रोक कर रखा जाए। किसी भी स्थिति में, अपग्रेड पैक्ड बाइनरी को बदल देता है जबकि पुरानी dockerd चलती रहती है, और needs-restarting वह कमांड है जो आपको बताती है कि कौन सी सेवाएं अभी भी उस कोड को चला रही हैं जिसे आपने अभी बदला है।

क्या podman पहले से ही docker कमांड का उत्तर दे रहा है?

Rocky Linux और AlmaLinux अपने डिफ़ॉल्ट रिपॉजिटरी में podman प्रदान करते हैं, और कई VPS इमेज इसे आपके लिए पहले से इंस्टॉल कर देती हैं। कुछ इमेज इससे आगे बढ़कर podman-docker इंस्टॉल करती हैं, जो /usr/bin/docker पर एक शेल स्क्रिप्ट रखती है और podman को कॉल करती है। इसके बाद आप जो भी docker कमांड टाइप करते हैं, वह वास्तव में podman चलाता है, इसलिए Docker के लिए लिखा गया गाइड आपको अप्रत्याशित परिणाम दे सकता है।

इसका पहला संकेत एक बैनर है। /usr/bin/docker स्क्रिप्ट /etc/containers/nodocker फ़ाइल की जाँच करती है, और जब वह फ़ाइल मौजूद नहीं होती है, तो यह कुछ भी चलाने से पहले एक लाइन प्रिंट करती है:

Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.

हो सकता है कि किसी ने बैनर को साइलेंस करने के लिए वह फ़ाइल बना दी हो, इसलिए केवल उस पर निर्भर न रहें। पैकेज डेटाबेस से पूछें कि बाइनरी किस पैकेज के स्वामित्व में है:

command -v docker
rpm -qf "$(command -v docker)"

यदि उत्तर podman-docker से शुरू होता है, तो इसका मतलब है कि podman उत्तर दे रहा है। यदि उत्तर docker-ce-cli से शुरू होता है, तो इसका मतलब है कि यह वास्तविक Docker है। यदि rpm -qf रिपोर्ट करता है कि कोई भी पैकेज फ़ाइल का स्वामी नहीं है, तो किसी ने इसे मैन्युअल रूप से इंस्टॉल किया है और उस पर भरोसा करने से पहले आपको स्क्रिप्ट को पढ़ लेना चाहिए।

Podman उन्हीं OCI इमेज को चलाता है और एक उचित विकल्प है। यदि आप इसे चाहते हैं, तो यहीं रुक जाएं। दोनों Linux कंटेनर इंजन हैं, इसलिए यदि प्लेटफॉर्म का निर्णय अभी भी खुला है, तो यह जानना उपयोगी है कि FreeBSD jails रजिस्ट्री से ली गई लेयर्ड इमेज चलाने के बजाय एक पूर्ण userland को आइसोलेट करती हैं। यदि आप Docker Engine चाहते हैं, तो पहले परस्पर विरोधी (conflicting) पैकेजों को हटा दें। यह वह सूची है जिसे Docker ने RHEL के लिए प्रलेखित किया है:

sudo dnf remove docker docker-client docker-client-latest docker-common \
  docker-latest docker-latest-logrotate docker-logrotate docker-engine podman runc

पुष्टि करने से पहले पढ़ें कि dnf किन पैकेजों को हटाने की योजना बना रहा है। एक नई VPS इमेज पर यह सूची छोटी होती है। किसी ऐसे बॉक्स पर जिसे पहले ही इस्तेमाल किया जा चुका है, podman को हटाने से cockpit-podman या कोई अन्य टूल हट सकता है जो उस पर निर्भर है।

सिद्धांत रूप में podman को Docker के साथ रखना संभव है: केवल podman-docker को हटाएं, ताकि docker नाम खाली हो जाए, और runc को हटाएं, जिसे containerd.io पैकेज बदल देता है। Docker का डॉक्यूमेंटेशन podman को एक परस्पर विरोधी पैकेज मानता है, इसलिए यह लेआउट Docker द्वारा समर्थित नहीं है। यदि इंस्टॉलेशन अभी भी कॉन्फ़्लिक्ट की रिपोर्ट करता है, तो ऊपर दी गई पूर्ण निष्कासन सूची का उपयोग करें।

dnf config-manager के साथ Docker का repository जोड़ें

Docker, Enterprise Linux के लिए RPMs को download.docker.com पर प्रकाशित करता है। यह repository file CentOS tree की ओर इशारा करती है, जिसका उपयोग Rocky Linux और AlmaLinux भी करते हैं। Rocky box को CentOS repository की ओर निर्देशित करना तब तक गलत लग सकता है जब तक आप यह न जान लें कि 2020 में Red Hat द्वारा CentOS को Stream में बदलने के बाद दोनों distributions कैसे CentOS lineage से विकसित हुए। अगस्त 2026 में जाँच करने पर, Docker ने CentOS Stream 9 और CentOS Stream 10 के लिए इस repository को प्रमाणित किया है।

sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

dnf के version 5 ने --add-repo argument को हटा दिया है, इसलिए नए releases पर वह दूसरा command विफल हो जाता है। जाँचें कि आपके पास कौन सा version है, फिर उसके अनुसार सही form चुनें:

dnf --version

यदि यह 5.x version दिखाता है, तो इसके बजाय subcommand form का उपयोग करें:

sudo dnf config-manager addrepo --from-repofile=https://download.docker.com/linux/centos/docker-ce.repo

दोनों ही /etc/yum.repos.d/docker-ce.repo पर एक ही file लिखते हैं। गलत form का उपयोग करने पर यह चुपचाप गलत काम करने के बजाय unknown-argument error देता है, इसलिए आप इसे नजरअंदाज नहीं करेंगे।

वह repo file baseurl को एक ऐसे path पर set करती है जिसमें $releasever शामिल है, और dnf आपके release package से उस variable को expand करता है। Rocky Linux और AlmaLinux इसे major version number पर set करते हैं, जैसे EL 9 पर 9 और EL 10 पर 10, यही कारण है कि Rocky box पर CentOS repository सही ढंग से काम करती है। install करने से पहले expansion की पुष्टि करें:

sudo dnf repoinfo docker-ce-stable

Repo-baseurl line को पढ़ें। इसे /9/x86_64/stable या /10/x86_64/stable पर समाप्त होना चाहिए। यदि आपका release $releasever को 9.6 जैसे point version पर set करता है, तो metadata fetch करते समय dnf उस URL के लिए Status code: 404 की रिपोर्ट देगा। इसे ठीक करने के लिए /etc/yum.repos.d/docker-ce.repo को edit करें और $releasever को केवल major number से बदलें।

इंजन और compose प्लगइन इंस्टॉल करें

sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

इसमें पाँच पैकेज हैं, और प्रत्येक का एक विशिष्ट कार्य है। docker-ce डेमन (daemon) है, dockerd। docker-ce-cli वह docker कमांड है जिसे आप टाइप करते हैं। containerd.io वह कंटेनर रनटाइम है जिसे डेमन संचालित करता है। docker-buildx-plugin इमेज बनाता है। docker-compose-plugin, docker compose को सब-कमांड के रूप में प्रदान करता है।

ये पैकेज हाइफन वाला docker-compose बाइनरी इंस्टॉल नहीं करते हैं। वह Compose v1 था, जो जुलाई 2023 में समाप्त (end of life) हो गया। जो कुछ भी हाइफन के साथ docker-compose को कॉल करता है, उसे स्पेस के साथ docker compose में अपडेट करने की आवश्यकता है।

पहला इंस्टॉलेशन Docker की साइनिंग की (signing key) को इम्पोर्ट करने के लिए रुकता है और आपको उसका फिंगरप्रिंट दिखाता है। यह की (key) आपके द्वारा अभी जोड़े गए रेपो फ़ाइल में gpgkey=https://download.docker.com/linux/centos/gpg से आती है, इसलिए इसे स्वीकार करने से पहले dnf द्वारा प्रिंट किए गए फिंगरप्रिंट की उस URL से तुलना करें।

एक विफलता इतनी बार होती है कि उसका उल्लेख करना आवश्यक है। यदि dnf रिपोर्ट करता है कि containerd.io को container-selinux की आवश्यकता है और कोई भी इसे प्रदान नहीं कर रहा है, तो आपका AppStream रिपॉजिटरी डिसेबल है। dnf repolist चलाएँ और पुष्टि करें कि appstream लिस्ट में है, क्योंकि EL 9 और EL 10 पर container-selinux यहीं से मिलता है।

Docker को start करें और सुनिश्चित करें कि यह चल रहा है

sudo systemctl enable --now docker
sudo systemctl status docker --no-pager
sudo docker run --rm hello-world

Docker के RPM packages install होने के बाद daemon को stopped और disabled छोड़ देते हैं। यही कारण है कि यह चरण Docker के CentOS page पर दिखाई देता है, न कि इसके Ubuntu page पर, जहाँ deb package आपके लिए service को start कर देता है। यदि आप enable को छोड़ देते हैं, तो Docker अगले reboot तक चलेगा, फिर बंद हो जाएगा और अपने साथ सभी containers को भी बंद कर देगा।

systemctl status को Active: active (running) दिखाना चाहिए। hello-world container को This message shows that your installation appears to be working correctly. print करना चाहिए और exit हो जाना चाहिए। यदि इसके बजाय यह /var/run/docker.sock पर permission error print करता है, तो आपने sudo को छोड़ दिया है, जिसे नीचे दिया गया docker group section ठीक कर देगा।

Compose plugin की अलग से जाँच करें, क्योंकि यह एक अलग package है और engine के ठीक होने के बावजूद यह missing हो सकता है:

docker compose version

एक सही परिणाम Docker Compose version v2.x.x जैसा दिखता है। Reboot के बाद अपनी services को वापस पाना daemon को enable करने से अलग विषय है, और restart policies यह तय करती हैं कि क्या Compose services boot पर वापस आएँगी।

Bind mount में permission denied क्यों आता है?

Rocky Linux और AlmaLinux डिफ़ॉल्ट रूप से SELinux (Security-Enhanced Linux) को enforcing मोड में चलाते हैं। इसकी पुष्टि getenforce से करें, जो Enforcing प्रिंट करता है।

Docker containers container_t SELinux टाइप के तहत चलते हैं, और यह टाइप केवल उन फाइलों को पढ़ और लिख सकता है जिन्हें container_file_t लेबल किया गया है। होस्ट पर आपके द्वारा बनाई गई डायरेक्टरी को वही लेबल मिलता है जो उसके पैरेंट पाथ का होता है, जो कि container_file_t नहीं होता। होस्ट साइड से ओनर, ग्रुप और मोड सही दिखने के बावजूद कंटेनर को एक्सेस करने से मना कर दिया जाता है। इसे तीन कमांड्स से दोहराया जा सकता है:

sudo mkdir -p /srv/site
echo hello | sudo tee /srv/site/index.html
sudo docker run --rm -v /srv/site:/usr/share/nginx/html:ro nginx:alpine cat /usr/share/nginx/html/index.html

कंटेनर यह प्रिंट करता है:

cat: can't open '/usr/share/nginx/html/index.html': Permission denied

दो कमांड्स आपको इसका कारण दिखाती हैं। ls -ldZ /srv/site लेबल प्रिंट करता है, जो /srv के अंतर्गत किसी पाथ के लिए system_u:object_r:var_t:s0 होता है, न कि container_file_t। फिर sudo ausearch -m avc -ts recent कर्नल का ऑडिट रिकॉर्ड प्रिंट करता है, जिसमें avc: denied { read }, container_t को नाम देने वाला एक scontext= फील्ड, और आपके द्वारा डायरेक्टरी पर देखे गए लेबल को नाम देने वाला एक tcontext= फील्ड होता है। उन दो फील्ड्स के बीच का बेमेल ही पूरी समस्या है।

इसका समाधान वॉल्यूम आर्गुमेंट में एक सफिक्स जोड़ना है। Docker आपके लिए पाथ को रीलेबल कर देता है:

sudo docker run --rm -v /srv/site:/usr/share/nginx/html:ro,z nginx:alpine cat /usr/share/nginx/html/index.html

लोअरकेस में :z कंटेंट को shared के रूप में रीलेबल करता है, ताकि कई कंटेनर एक ही डायरेक्टरी का उपयोग कर सकें। अपरकेस में :Z इसे private और unshared के रूप में रीलेबल करता है, जो एक कंटेनर से जुड़ा होता है, और उसी पाथ को पढ़ने वाले दूसरे कंटेनर को मना कर दिया जाता है। किसी भी ऐसी चीज़ के लिए :z का उपयोग करें जिसे sidecar या backup कंटेनर भी एक्सेस करता है। एक डेटाबेस डायरेक्टरी के लिए :Z का उपयोग करें जिसका मालिक केवल एक कंटेनर है।

Docker के डॉक्यूमेंटेशन में एक चेतावनी है जिसे दोहराना आवश्यक है, क्योंकि रीलेबलिंग रिकर्सिव (recursive) होती है। :Z के साथ /home या /usr जैसी सिस्टम डायरेक्टरी को bind-mount करने से "आपकी होस्ट मशीन काम करना बंद कर सकती है और आपको होस्ट मशीन की फाइलों को मैन्युअल रूप से रीलेबल करना पड़ सकता है"। इन सफिक्स का उपयोग केवल उन डायरेक्टरीज़ के लिए करें जिन्हें आपने कंटेनर के लिए बनाया है, कभी भी सिस्टम पाथ पर इनका उपयोग न करें।

Compose में सफिक्स उसी स्ट्रिंग पर लगाया जाता है:

services:
  web:
    image: nginx:alpine
    volumes:
      - /srv/site:/usr/share/nginx/html:ro,z

दो सीमाएँ ऐसी हैं जिन्हें पार करना आसान है। --mount फ्लैग SELinux लेबल सेट नहीं कर सकता, इसलिए जब आपको इसकी आवश्यकता हो तो -v का उपयोग करें। Named volumes को किसी सफिक्स की आवश्यकता नहीं होती, क्योंकि Docker स्वयं /var/lib/docker/volumes के अंतर्गत बनाई गई डायरेक्टरीज़ को लेबल करता है।

SELinux को बंद न करें। sudo setenforce 0 का उपयोग केवल एक मिनट के टेस्ट के रूप में करें: यदि कंटेनर तब काम करता है, तो समस्या लेबल की है और :z इसका उत्तर है। इसे तुरंत sudo setenforce 1 के साथ वापस चालू करें। Enterprise Linux पर, bind mount पर permission denied के दो अलग-अलग कारण होते हैं जो कंटेनर के अंदर से एक जैसे दिखते हैं। एक SELinux लेबल है। दूसरा सामान्य न्यूमेरिक यूजर और ग्रुप ओनरशिप है, जिसे PUID और PGID वेरिएबल्स हल करते हैं। ls -lnZ आपको एक ही लाइन में मोड, न्यूमेरिक ओनर और लेबल दिखाता है, ताकि आप जान सकें कि आप किस समस्या का सामना कर रहे हैं।

जब firewalld बंद दिखता है, तब भी published port तक पहुँच क्यों संभव है?

Rocky Linux और AlmaLinux पर firewalld डिफ़ॉल्ट फ़ायरवॉल है। sudo systemctl is-active firewalld के साथ जाँचें कि यह चल रहा है या नहीं। यदि आपने इस बॉक्स पर अभी तक इसे कॉन्फ़िगर नहीं किया है, तो opening SSH and a web port with firewalld पहले करें, क्योंकि नीचे दी गई स्थिति तभी समझ में आती है जब आपके पास तुलना करने के लिए एक कार्यशील ज़ोन रूल्सेट हो। अब एक पोर्ट पब्लिश करें और देखें कि firewalld क्या खुला मानता है:

sudo docker run -d --name web -p 8080:80 nginx:alpine
sudo firewall-cmd --list-ports

firewall-cmd एक खाली लाइन प्रिंट करता है। किसी अन्य मशीन से, curl -I http://YOUR_SERVER_IP:8080/ का परिणाम HTTP/1.1 200 OK आता है। पोर्ट इंटरनेट के लिए खुला है और आपका फ़ायरवॉल कुछ भी रिपोर्ट नहीं कर रहा है।

इसका कारण वह रास्ता है जिससे पैकेट गुजरता है। Firewalld के ज़ोन नियम होस्ट को संबोधित ट्रैफ़िक को फ़िल्टर करते हैं। एक published port होस्ट को संबोधित नहीं होता है: Docker एक destination NAT (network address translation) नियम स्थापित करता है जो पैकेट के होस्ट के इनपुट पाथ तक पहुँचने से पहले डेस्टिनेशन को कंटेनर के पते पर फिर से लिख देता है, इसलिए कर्नल पैकेट को स्थानीय रूप से डिलीवर करने के बजाय फॉरवर्ड कर देता है। इसके बाद Docker अपने ब्रिज इंटरफेस को docker नामक firewalld ज़ोन में रखता है जिसका टारगेट ACCEPT है, और docker-forwarding नामक एक फॉरवर्डिंग पॉलिसी जोड़ता है जो किसी भी ज़ोन से docker ज़ोन में फॉरवर्डिंग की अनुमति देती है। आपके ज़ोन नियम पैकेट को कभी नहीं देख पाते हैं।

सबसे साफ समाधान के लिए किसी फ़ायरवॉल नियम की आवश्यकता नहीं है। पब्लिश के होस्ट साइड को loopback पर बाइंड करें और इसके सामने एक reverse proxy रखें:

sudo docker rm -f web
sudo docker run -d --name web -p 127.0.0.1:8080:80 nginx:alpine
curl -I http://127.0.0.1:8080/

स्थानीय curl का परिणाम HTTP/1.1 200 OK आता है और किसी अन्य मशीन से वही अनुरोध अब कनेक्ट नहीं होता है। -p आर्ग्युमेंट में बिना होस्ट एड्रेस वाली कोई भी चीज़ हर इंटरफेस पर पब्लिश हो जाती है, इसलिए एक खाली -p 8080:80 को उस सर्विस को सार्वजनिक रूप से एक्सपोज़ करने के निर्णय के रूप में देखें।

जब आपको किसी सर्विस को कुछ पतों से सुलभ और दूसरों से नहीं रखना हो, तो Docker आपके लिए एक चेन रिज़र्व करता है। DOCKER-USER को Docker के अपने accept नियमों से पहले प्रोसेस किया जाता है, इसलिए आपके द्वारा वहां रखा गया नियम Docker के रीस्टार्ट होने और अपनी चेन को फिर से लिखने के बाद भी बना रहता है:

sudo iptables -I DOCKER-USER -i enp1s0 ! -s 203.0.113.10 -j DROP
sudo iptables -S DOCKER-USER

इंटरफेस का नाम ip route show default से लें, न कि eth0 मानकर चलें, क्योंकि वर्तमान EL इमेजेस enp1s0 या ens3 जैसे नामों का उपयोग करती हैं। Rocky और AlmaLinux पर iptables कमांड nftables के ऊपर एक कम्पैटिबिलिटी लेयर है, और Docker की चेन इसके माध्यम से दिखाई देती है। इस तरह जोड़े गए नियम रीबूट के बाद हट जाते हैं जब तक कि आप उन्हें सेव न करें, इसलिए जब आप उनसे संतुष्ट हों तो उन्हें एक systemd यूनिट में लिख लें।

Docker Engine 28.0, जिसे 2025 में रिलीज़ किया गया था, ने एक संबंधित खामी को बंद कर दिया: कंटेनर पोर्ट्स तक सीधा रूटेड एक्सेस जो कभी पब्लिश नहीं किए गए थे, अब DOCKER चेन में ब्लॉक कर दिए गए हैं। वह बदलाव पब्लिश किए गए पोर्ट्स को प्रभावित नहीं करता है, इसलिए वर्तमान वर्जन्स पर ऊपर दी गई सभी बातें लागू होती हैं। एक ऑपरेशनल आदत डालना उचित है: किसी भी sudo firewall-cmd --reload के बाद, एक published port का पुनः परीक्षण करें। यदि उसने जवाब देना बंद कर दिया है, तो sudo systemctl restart docker Docker के नियमों को फिर से इंस्टॉल कर देता है।

Ubuntu एडमिनिस्ट्रेटर एक अलग टूल के माध्यम से इसी बाधा का सामना करते हैं, जो why published Docker ports ignore ufw rules का कारण है। दोनों ही मामलों में NAT पाथ ही मूल कारण है। केवल इसके सामने का फ़ायरवॉल बदलता है।

docker group में एक non-root user जोड़ना

हर sudo कमांड से पहले docker टाइप करना थकाऊ हो जाता है, और docker group इस आवश्यकता को खत्म कर देता है:

sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-world

usermod -aG, /etc/group को एडिट करता है, लेकिन आपके वर्तमान shell में पहले से ही group list मौजूद है, इसलिए यह बदलाव तब तक लागू नहीं होगा जब तक आप एक नया shell session शुरू नहीं करते। newgrp docker एक ऐसा shell शुरू करता है जिसमें यह group जुड़ा होता है, ताकि आप तुरंत परीक्षण कर सकें। नए SSH sessions इसे अपने आप उठा लेते हैं।

यह स्पष्ट रखें कि यह group क्या अधिकार देता है। इसकी सदस्यता /var/run/docker.sock तक write access प्रदान करती है, और जो भी इस socket से बात कर सकता है, वह daemon को एक ऐसा container शुरू करने के लिए कह सकता है जो host filesystem को mount करता हो। एक कमांड दिखाती है कि इसका क्या अर्थ है:

docker run --rm -v /:/host alpine wc -l /host/etc/shadow

यह एक ऐसी file को पढ़ता है जिसे केवल root ही पढ़ सकता है, वह भी एक ऐसे account से जिसके पास कोई sudo अधिकार नहीं हैं। Docker का अपना post-install documentation भी यही कहता है: docker group root के बराबर विशेषाधिकार (privileges) देता है। किसी account को इसमें तभी जोड़ें यदि आप उस account को sudo भी देना चाहते हों। यदि आप एक नए server पर accounts सेट कर रहे हैं, तो इस निर्णय को बाद में लेने के बजाय VPS पर least-privilege user setup के साथ ही तय करें।

Docker एक rootless mode भी प्रदान करता है जो daemon को एक unprivileged user के रूप में चलाता है। यह एक अलग install path है और यह storage drivers तथा 1024 से नीचे के ports के व्यवहार को बदल देता है, इसलिए इसे बाद में जोड़ने वाले एक flag के बजाय एक अलग project के रूप में योजनाबद्ध करें।

आगे क्या करें

अब आपके पास engine, compose plugin, reboot के बाद भी चलने वाली service, और ऊपर वर्णित तीन EL-विशिष्ट व्यवहार मौजूद हैं। अगला कदम प्रति service एक compose.yaml बनाना है, और Compose file की संरचना में file format और उसे संचालित करने वाले commands की जानकारी दी गई है। यदि यह आपका पहला container host है, तो VPS पर Docker चलाना उन sizing, storage और image-hygiene संबंधी सवालों को कवर करता है जिन्हें इस guide में शामिल नहीं किया गया है।

FAQ

क्या Docker का CentOS repository Rocky Linux और AlmaLinux पर काम करता है?

हाँ। https://download.docker.com/linux/centos/docker-ce.repo को dnf config-manager के साथ जोड़ें। उस फाइल में मौजूद baseurl में $releasever होता है, और Rocky Linux तथा AlmaLinux इसे major version number में बदल देते हैं। इसलिए, एक EL 9 बॉक्स CentOS 9 tree पर और एक EL 10 बॉक्स CentOS 10 tree पर resolve होता है। sudo dnf repoinfo docker-ce-stable के साथ इस expansion की पुष्टि करें और Repo-baseurl लाइन को पढ़ें। dnf द्वारा metadata fetch करते समय Status code: 404 आने का मतलब है कि variable एक point release पर expand हुआ है, और /etc/yum.repos.d/docker-ce.repo को एडिट करके केवल major number का उपयोग करने से यह ठीक हो जाता है।

क्या Docker और podman एक ही सर्वर पर install किए जा सकते हैं?

Docker का documentation podman और runc को परस्पर विरोधी packages के रूप में सूचीबद्ध करता है और Docker Engine install करने से पहले दोनों को हटाने का निर्देश देता है। वास्तविक टकराव podman-docker package के कारण होता है, जो /usr/bin/docker का मालिक है और हर docker कमांड को podman कमांड में बदल देता है। यह देखने के लिए कि उस path का मालिक कौन सा package है, rpm -qf "$(command -v docker)" चलाएँ। यदि output podman-docker से शुरू होता है, तो podman जवाब दे रहा है। दोनों engines को एक साथ रखना ऐसा layout नहीं है जिसका Docker समर्थन करता है, इसलिए महत्वपूर्ण सर्वर पर किसी एक को चुनें।

bind mount पर मेरे container को permission denied क्यों मिलता है?

Rocky Linux और AlmaLinux पर SELinux डिफ़ॉल्ट रूप से लागू (enforcing) होता है। Containers container_t type के रूप में चलते हैं और केवल container_file_t लेबल वाली फाइलों को ही छू सकते हैं। इसलिए, आपके द्वारा बनाई गई directory में गलत लेबल होता है और उसके owner या mode के बावजूद access denied हो जाता है। host path पर ls -ldZ के साथ इसकी पुष्टि करें और sudo ausearch -m avc -ts recent चलाएँ, जो दो बेमेल contexts के साथ avc: denied प्रिंट करता है। Containers के बीच साझा की जाने वाली सामग्री के लिए volume argument में :z जोड़ें, या किसी एक container के लिए निजी सामग्री हेतु :Z का उपयोग करें। :Z को कभी भी /home या /usr पर पॉइंट न करें, क्योंकि relabeling recursive होती है और host को खराब कर देगी।

क्या container port publish करने के लिए मुझे firewalld में port खोलना पड़ता है?

नहीं, और यही समस्या है। Docker का NAT rule पैकेट के host के input path तक पहुँचने से पहले destination address को rewrite कर देता है, इसलिए firewalld के zone rules इसे कभी inspect नहीं करते। Docker अपने bridges को docker नामक firewalld zone में भी रखता है जिसका target ACCEPT होता है। -p 8080:80 के साथ शुरू किया गया container इंटरनेट से पहुँच योग्य होता है जबकि sudo firewall-cmd --list-ports कुछ भी प्रिंट नहीं करता। जब केवल host को ही service तक पहुँचना हो, तो -p 127.0.0.1:8080:80 के साथ किसी विशिष्ट address पर publish करें, या DOCKER-USER chain में filtering rules डालें, जिसे Docker अपने स्वयं के accept rules से पहले process करता है।

क्या अपने user को docker group में जोड़ना सुरक्षित है?

यह root access प्रदान करता है। docker group का सदस्य /var/run/docker.sock में लिख सकता है, और docker run --rm -v /:/host alpine wc -l /host/etc/shadow फिर बिना sudo अधिकारों वाले account से root-only फाइल पढ़ सकता है। Docker का post-install documentation भी इसी समानता को बताता है। केवल उन्हीं accounts को जोड़ें जिन पर आप पहले से ही sudo के साथ भरोसा करते हैं, और shared या service accounts के लिए sudo docker का उपयोग करना जारी रखें। जब आपको unprivileged user के तहत containers की आवश्यकता हो, तो Rootless mode एक विकल्प है, और यह एक सेटिंग के बजाय एक अलग install path है।