SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-12

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

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

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

Rocky Linux या AlmaLinux पर Docker इंस्टॉल करने के लिए, आपको Docker की अपनी dnf repository जोड़नी होगी, compose plugin के साथ engine इंस्टॉल करना होगा, और फिर service को enable करना होगा। यह प्रक्रिया चार commands में पूरी होती है, और दोनों distributions पर समान है क्योंकि दोनों Red Hat Enterprise Linux (RHEL) के rebuilds हैं और एक ही package layout साझा करते हैं। CentOS Stream पर भी यही प्रक्रिया काम करती है।

इंस्टॉल करने की प्रक्रिया छोटी है, इसलिए इस गाइड का अधिकांश हिस्सा यह बताता है कि Enterprise Linux (EL) Ubuntu से किस प्रकार भिन्न है। हो सकता है कि आपकी image पर Podman पहले से ही docker command का उपयोग कर रहा हो। SELinux bind-mounted files को तब तक block करता है जब तक उन पर सही label न लगा हो। Firewalld Docker के published ports को filter नहीं करता है, इसलिए एक container port internet के लिए खुला हो सकता है जबकि firewall-cmd यह रिपोर्ट करता है कि कुछ भी खुला नहीं है।

get.docker.com से Docker की convenience script का उपयोग न करें। Docker का अपना documentation कहता है कि production के लिए इसकी अनुशंसा नहीं की जाती है। यह बिना पूछे आपकी repository configuration को फिर से लिख देती है, और इसे upgrade करने के लिए सुरक्षित रूप से दोबारा नहीं चलाया जा सकता है। repository को मैन्युअल रूप से जोड़ने का मतलब है कि dnf upgrade Docker को box पर मौजूद अन्य सभी packages की तरह ही treat करता है।

क्या 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 इमेज को चलाता है और यह एक उचित विकल्प है। यदि आप इसे ही चाहते हैं, तो यहीं रुक जाएं। यदि आप 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 इस लेआउट का समर्थन नहीं करता है। यदि इंस्टॉलेशन अभी भी किसी विरोध (conflict) की रिपोर्ट करता है, तो ऊपर दी गई पूर्ण निष्कासन सूची का उपयोग करें।

dnf config-manager के साथ Docker का रिपॉजिटरी जोड़ें

Docker, Enterprise Linux के लिए RPMs को download.docker.com पर प्रकाशित करता है। रिपॉजिटरी फ़ाइल CentOS ट्री की ओर इशारा करती है, जिसका उपयोग Rocky Linux और AlmaLinux भी करते हैं। अगस्त 2026 में जाँच करने पर, Docker ने CentOS Stream 9 और CentOS Stream 10 के लिए इस रिपॉजिटरी को प्रमाणित किया है।

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

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

dnf --version

यदि यह 5.x वर्जन दिखाता है, तो इसके बजाय सब-कमांड फॉर्म का उपयोग करें:

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

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

वह रेपो फ़ाइल baseurl को एक ऐसे पथ पर सेट करती है जिसमें $releasever शामिल है, और dnf आपके रिलीज़ पैकेज से उस वेरिएबल को एक्सपैंड (expand) करता है। Rocky Linux और AlmaLinux इसे मेजर वर्जन नंबर पर सेट करते हैं, जैसे EL 9 पर 9 और EL 10 पर 10, यही कारण है कि एक CentOS रिपॉजिटरी Rocky सिस्टम पर सही ढंग से काम करती है। इंस्टॉल करने से पहले एक्सपेंशन की पुष्टि करें:

sudo dnf repoinfo docker-ce-stable

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

Engine और compose plugin को install करें

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

यहाँ पाँच packages हैं, और हर एक का अपना एक काम है। docker-ce daemon है, dockerddocker-ce-cli वह docker command है जिसे आप type करते हैं। containerd.io वह container runtime है जिसे daemon चलाता है। docker-buildx-plugin images को build करता है। docker-compose-plugin, docker compose को एक subcommand के रूप में प्रदान करता है।

ये packages hyphen वाला docker-compose binary install नहीं करते हैं। वह Compose v1 था, जो July 2023 में end of life हो चुका है। जो भी script या command hyphen के साथ docker-compose को call करती है, उसे space के साथ docker compose में update करने की आवश्यकता है।

पहली बार install करते समय, Docker की signing key को import करने के लिए प्रक्रिया रुकती है और आपको उसका fingerprint दिखाया जाता है। यह key आपके द्वारा अभी add की गई repo file में मौजूद gpgkey=https://download.docker.com/linux/centos/gpg से आती है, इसलिए accept करने से पहले dnf द्वारा दिखाए गए fingerprint की तुलना उस URL से करें।

एक विफलता (failure) इतनी बार होती है कि उसका उल्लेख करना आवश्यक है। यदि dnf यह report करता है कि containerd.io को container-selinux की आवश्यकता है और कोई भी package इसे प्रदान नहीं कर रहा है, तो इसका मतलब है कि आपका AppStream repository disabled है। 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 पेज पर दिखाई देता है, न कि इसके Ubuntu पेज पर, जहाँ 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 देता है, तो आपने sudo को छोड़ दिया है, जिसे नीचे दिए गए docker group अनुभाग द्वारा ठीक किया जा सकता है।

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

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, SELinux type container_t के अंतर्गत चलते हैं, और यह type केवल उन्हीं फाइलों को पढ़ और लिख सकता है जिन्हें 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 } होता है, एक scontext= फील्ड जो container_t को नाम देता है, और एक 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) होती है। /home या /usr जैसी सिस्टम डायरेक्टरी को :Z के साथ 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 के साथ जाँचें कि क्या यह चल रहा है। अब एक port publish करें और देखें कि 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 मिलता है। Port इंटरनेट के लिए खुला है, लेकिन आपका फ़ायरवॉल कुछ नहीं दिखा रहा है।

इसका कारण वह रास्ता है जिससे पैकेट गुजरता है। Firewalld के zone rules केवल उस ट्रैफ़िक को फ़िल्टर करते हैं जो सीधे host के लिए होता है। Published port host के लिए संबोधित नहीं होता: Docker एक destination NAT (network address translation) नियम स्थापित करता है जो पैकेट के host के input path तक पहुँचने से पहले ही destination को container के पते पर बदल देता है, इसलिए kernel पैकेट को स्थानीय रूप से डिलीवर करने के बजाय forward कर देता है। इसके बाद Docker अपने bridge interfaces को docker नामक firewalld zone में डाल देता है जिसका target ACCEPT है, और एक forwarding policy docker-forwarding जोड़ता है जो किसी भी zone से docker zone में forwarding की अनुमति देती है। आपके zone rules पैकेट को कभी देख ही नहीं पाते।

सबसे साफ़ समाधान के लिए किसी फ़ायरवॉल नियम की आवश्यकता नहीं है। Publish के host side को loopback पर bind करें और उसके सामने एक 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 मिलता है और किसी अन्य मशीन से वही अनुरोध अब connect नहीं होता। -p argument में बिना host address वाली कोई भी चीज़ हर interface पर publish हो जाती है, इसलिए बिना किसी पते के -p 8080:80 का उपयोग करने का अर्थ है उस सेवा को सार्वजनिक रूप से expose करना।

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

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

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

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

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

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

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

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

आगे क्या करें

अब आपके पास 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 रिपॉजिटरी Rocky Linux और AlmaLinux पर काम करता है?

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

क्या Docker और podman को एक ही सर्वर पर इंस्टॉल किया जा सकता है?

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

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

Rocky Linux और AlmaLinux पर SELinux डिफ़ॉल्ट रूप से लागू होता है। कंटेनर container_t टाइप के रूप में चलते हैं और केवल container_file_t लेबल वाली फाइलों को ही एक्सेस कर सकते हैं। इसलिए, आपके द्वारा बनाई गई डायरेक्टरी का लेबल गलत होता है और ओनर या मोड के बावजूद एक्सेस डिनाई हो जाता है। होस्ट पाथ पर ls -ldZ और sudo ausearch -m avc -ts recent से इसकी पुष्टि करें, जो दो बेमेल कॉन्टेक्स्ट के साथ avc: denied प्रिंट करता है। कंटेनरों के बीच साझा की जाने वाली सामग्री के लिए वॉल्यूम आर्ग्युमेंट में :z जोड़ें, या किसी एक कंटेनर के लिए निजी सामग्री हेतु :Z का उपयोग करें। :Z को कभी भी /home या /usr पर पॉइंट न करें, क्योंकि रीलेबलिंग रिकर्सिव होती है और होस्ट को खराब कर देगी।

क्या कंटेनर पोर्ट पब्लिश करने के लिए मुझे firewalld में पोर्ट खोलने की आवश्यकता है?

नहीं, और यही समस्या है। Docker का NAT रूल पैकेट के होस्ट के इनपुट पाथ तक पहुँचने से पहले डेस्टिनेशन एड्रेस को फिर से लिख देता है, इसलिए firewalld के ज़ोन रूल्स इसे कभी चेक नहीं करते। Docker अपने ब्रिजों को docker नामक firewalld ज़ोन में रखता है जिसका टारगेट ACCEPT होता है। -p 8080:80 के साथ शुरू किया गया कंटेनर इंटरनेट से एक्सेस किया जा सकता है जबकि sudo firewall-cmd --list-ports कुछ भी प्रिंट नहीं करता है। जब केवल होस्ट को ही सर्विस तक पहुँचना हो, तो -p 127.0.0.1:8080:80 के साथ किसी विशिष्ट एड्रेस पर पब्लिश करें, या DOCKER-USER चेन में फिल्टरिंग रूल्स डालें, जिसे Docker अपने स्वयं के एक्सेप्ट रूल्स से पहले प्रोसेस करता है।

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

यह root एक्सेस प्रदान करता है। docker ग्रुप का सदस्य /var/run/docker.sock में लिख सकता है, और docker run --rm -v /:/host alpine wc -l /host/etc/shadow फिर बिना sudo अधिकारों वाले अकाउंट से root-ओनली फाइल पढ़ सकता है। Docker का पोस्ट-इंस्टॉल डॉक्यूमेंटेशन भी इसी समानता की पुष्टि करता है। केवल उन्हीं अकाउंट्स को जोड़ें जिन पर आप पहले से ही sudo के साथ भरोसा करते हैं, और साझा या सर्विस अकाउंट्स के लिए sudo docker का उपयोग करना जारी रखें। जब आपको अनप्रिविलेज्ड यूजर के तहत कंटेनर चलाने की आवश्यकता हो, तो Rootless मोड एक विकल्प है, और यह एक सेटिंग के बजाय एक अलग इंस्टॉलेशन पाथ है।