SSD Nodes Learn 🎉 VPS $5.50/ماہ سے
تعلیمی Matt Connorتحریر: Matt Connor · اپ ڈیٹ شدہ 2026-08-13

Rocky Linux یا AlmaLinux پر Docker انسٹال کریں

Rocky Linux یا AlmaLinux پر Docker Engine انسٹال کرنے کے لیے dnf repository اور Compose plugin استعمال کریں، پھر Podman کے docker command اور SELinux bind mounts کے مسائل حل کریں۔

Rocky Linux اور AlmaLinux پر Docker انسٹال کریں

Rocky Linux یا AlmaLinux پر Docker انسٹال کرنے کے لیے Docker کی اپنی dnf repository شامل کریں، engine کو compose plugin کے ساتھ انسٹال کریں، پھر service کو enable کریں۔ اس کے لیے چار commands درکار ہیں، اور دونوں distributions پر طریقہ یکساں ہے کیونکہ دونوں Red Hat Enterprise Linux (RHEL) کے rebuilds ہیں اور ایک ہی package layout استعمال کرتی ہیں۔ CentOS Stream بھی اسی طرح کام کرتا ہے۔

یہ installation مختصر ہے، اس لیے اس guide کا زیادہ حصہ ان فرقوں پر مرکوز ہے جو Enterprise Linux (EL) میں Ubuntu کے مقابلے میں موجود ہیں۔ آپ کی image میں Podman پہلے ہی docker command کا مالک ہو سکتا ہے۔ SELinux bind-mounted files کو اس وقت تک block کرتا ہے جب تک ان پر درست label نہ لگا ہو۔ Firewalld، Docker کے published ports کو filter نہیں کرتا، اس لیے کوئی container port internet کے لیے کھلا ہو سکتا ہے جبکہ firewall-cmd رپورٹ کرے کہ کچھ بھی open نہیں ہے۔

get.docker.com سے Docker کا convenience script استعمال نہ کریں۔ Docker کی اپنی documentation کے مطابق production کے لیے اس کی سفارش نہیں کی جاتی۔ یہ آپ سے پوچھے بغیر repository configuration کو rewrite کرتا ہے، اور upgrade کے لیے اسے محفوظ طریقے سے دوبارہ نہیں چلایا جا سکتا۔ Repository دستی طور پر شامل کرنے سے dnf upgrade Docker کو سسٹم کے ہر دوسرے package کی طرح manage کرتا ہے۔

کیا podman پہلے ہی docker کمانڈ کے جواب دے رہا ہے؟

Rocky Linux اور AlmaLinux اپنی default repositories میں podman فراہم کرتے ہیں، اور بہت سی VPS images اسے پہلے ہی install کر دیتی ہیں۔ کچھ images مزید آگے بڑھ کر podman-docker بھی install کرتی ہیں، جو /usr/bin/docker پر ایک shell script رکھتا ہے اور podman کو call کرتا ہے۔ اس کے بعد آپ جو بھی docker command لکھتے ہیں، وہ podman` کے ذریعے چلتی ہے۔ نتیجتاً Docker کے لیے لکھی گئی guide ایسا output پیدا کرتی ہے جس کی آپ کو توقع نہیں ہوتی۔

پہلی علامت ایک banner ہوتا ہے۔ /usr/bin/docker script /etc/containers/nodocker فائل موجود ہے یا نہیں، یہ check کرتی ہے۔ اگر فائل موجود نہ ہو تو کوئی بھی کام چلانے سے پہلے ایک سطر print کرتی ہے:

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

ممکن ہے کسی نے banner خاموش کرنے کے لیے یہ فائل بنائی ہو، اس لیے صرف اسی علامت پر انحصار نہ کریں۔ Package database سے پوچھیں کہ binary کس package کی ملکیت ہے:

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

اگر جواب podman-docker سے شروع ہو تو podman جواب دے رہا ہے۔ اگر جواب docker-ce-cli سے شروع ہو تو اصل Docker موجود ہے۔ اگر rpm -qf بتائے کہ کسی package کی یہ فائل ملکیت نہیں ہے، تو کسی نے اسے دستی طور پر install کیا ہے۔ ایسی صورت میں اس پر اعتماد کرنے سے پہلے script پڑھیں۔

Podman وہی OCI images چلاتا ہے اور ایک مناسب انتخاب ہے۔ اگر آپ اسے استعمال کرنا چاہتے ہیں تو یہاں رک جائیں۔ اگر آپ Docker Engine چاہتے ہیں تو پہلے متصادم packages remove کریں۔ یہ وہ فہرست ہے جسے Docker، RHEL کے لیے document کرتا ہے:

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

تصدیق کرنے سے پہلے دیکھیں کہ dnf ان packages کے ساتھ کیا remove کرنے کا منصوبہ بنا رہا ہے۔ ایک نئی VPS image پر فہرست مختصر ہوتی ہے۔ ایسے server پر جسے پہلے استعمال کیا جا چکا ہو، podman remove کرنے سے cockpit-podman یا اس پر منحصر کوئی دوسرا tool بھی remove ہو سکتا ہے۔

اصولی طور پر podman کو Docker کے ساتھ رکھنا ممکن ہے: صرف podman-docker remove کریں تاکہ docker نام آزاد ہو جائے، اور runc بھی remove کریں، جسے containerd.io package replace کرتا ہے۔ Docker کی documentation podman کو متصادم package سمجھتی ہے، اس لیے Docker اس configuration کو support نہیں کرتا۔ اگر installation پھر بھی conflict report کرے تو اوپر دی گئی مکمل removal list استعمال کریں۔

dnf config-manager کے ذریعے Docker کی repository شامل کریں

Docker، Enterprise Linux کے لیے RPMs download.docker.com پر شائع کرتا ہے۔ Repository file میں CentOS tree کا پتہ درج ہے، جس کے خلاف Rocky Linux اور AlmaLinux resolve کرتے ہیں۔ اگست 2026 میں جانچ کے وقت Docker نے اس repository کو CentOS Stream 9 اور CentOS Stream 10 کے لیے document کیا تھا۔

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

دونوں commands /etc/yum.repos.d/docker-ce.repo میں ایک ہی file لکھتی ہیں۔ غلط form unknown-argument error کے ساتھ ناکام ہوتی ہے؛ خاموشی سے غلط کام نہیں کرتی، اس لیے آپ اس خرابی کو نظر انداز نہیں کریں گے۔

یہ repo file baseurl کو ایسے path پر set کرتی ہے جس میں $releasever شامل ہے، اور dnf اس variable کی قدر آپ کے release package سے حاصل کرتا ہے۔ Rocky Linux اور AlmaLinux اسے major version number پر set کرتے ہیں۔ چنانچہ EL 9 پر 9 اور EL 10 پر 10 ہوتا ہے۔ اسی وجہ سے Rocky system پر CentOS repository درست resolve ہوتی ہے۔ 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 حاصل کرتے وقت 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

پانچ packages ہیں، اور ہر package ایک کام کرتا ہے۔ docker-ce daemon ہے، dockerd۔ docker-ce-cli وہ docker command ہے جو آپ ٹائپ کرتے ہیں۔ containerd.io وہ container runtime ہے جسے daemon چلاتا ہے۔ docker-buildx-plugin images بناتا ہے۔ docker-compose-plugin، docker compose کو subcommand کے طور پر فراہم کرتا ہے۔

یہ packages hyphen والا docker-compose binary انسٹال نہیں کرتے۔ یہ Compose v1 تھا، جس کی زندگی جولائی 2023 میں ختم ہو گئی۔ جو بھی چیز docker-compose کو hyphen کے ساتھ چلاتی ہے، اسے space کے ساتھ docker compose میں اپ ڈیٹ کرنا ضروری ہے۔

پہلی installation Docker کی signing key درآمد کرنے کے لیے رک جاتی ہے اور اس کا fingerprint دکھاتی ہے۔ یہ key اس repo file میں موجود gpgkey=https://download.docker.com/linux/centos/gpg سے حاصل ہوتی ہے جو آپ نے ابھی شامل کی ہے، اس لیے اسے قبول کرنے سے پہلے dnf کے دکھائے گئے fingerprint کا اس URL سے موازنہ کریں۔

ایک failure اتنی کثرت سے ظاہر ہوتی ہے کہ اسے الگ سے بیان کرنا ضروری ہے۔ اگر dnf بتائے کہ containerd.io کے لیے container-selinux درکار ہے اور کوئی package اسے فراہم نہیں کرتا، تو آپ کی AppStream repository disabled ہے۔ dnf repolist چلائیں اور تصدیق کریں کہ appstream درج ہے، کیونکہ EL 9 اور EL 10 پر container-selinux اسی repository میں release ہوتا ہے۔

Docker شروع کریں اور تصدیق کریں کہ یہ چل رہا ہے

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

Docker کے RPM packages انسٹالیشن کے بعد daemon کو stopped اور disabled حالت میں چھوڑ دیتے ہیں۔ اسی لیے یہ مرحلہ Docker کے CentOS صفحے پر موجود ہے، Ubuntu صفحے پر نہیں؛ وہاں deb آپ کے لیے service شروع کرتا ہے۔ enable کو چھوڑ دیں تو Docker اگلے reboot تک چلتا رہے گا، پھر بند ہو جائے گا اور اس کے ساتھ ہر container بھی رک جائے گا۔

systemctl status کا نتیجہ Active: active (running) ہونا چاہیے۔ hello-world container کو This message shows that your installation appears to be working correctly. پرنٹ کرکے بند ہو جانا چاہیے۔ اگر اس کے بجائے /var/run/docker.sock پر permission error دکھائی دے تو آپ نے sudo شامل نہیں کیا۔ ذیل کا docker group section اسے درست کرتا ہے۔

compose plugin کو الگ سے check کریں، کیونکہ یہ مختلف 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) کو default طور پر enforcing mode میں چلاتے ہیں۔ getenforce سے تصدیق کریں؛ یہ Enforcing دکھاتا ہے۔

Docker containers، SELinux type container_t کے تحت چلتے ہیں، اور یہ type صرف container_file_t سے label کی گئی files کو پڑھ اور لکھ سکتا ہے۔ Host پر بنائی گئی directory کو اس کے parent path کا label ملتا ہے، جو container_file_t نہیں ہوتا۔ Host کی طرف سے owner، group اور mode درست نظر آنے کے باوجود container کو رسائی سے روک دیا جاتا ہے۔ اسے تین commands سے دوبارہ بنائیں:

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

Container یہ output دکھاتا ہے:

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

دو commands وجہ ظاہر کرتی ہیں۔ ls -ldZ /srv/site label دکھاتا ہے۔ /srv کے تحت موجود path کے لیے یہ system_u:object_r:var_t:s0 ہوتا ہے، container_file_t نہیں۔ پھر sudo ausearch -m avc -ts recent kernel کا audit record دکھاتا ہے۔ اس میں avc: denied { read } شامل ہوتا ہے، جو container_t کا نام بتانے والا scontext= field ہے، اور tcontext= field اس label کا نام بتاتا ہے جو آپ نے ابھی directory پر دیکھا ہے۔ ان دونوں fields کے درمیان mismatch ہی پوری وجہ ہے۔

اس کا حل volume argument کے آخر میں suffix لگانا ہے۔ Docker path کو خود relabel کر دیتا ہے:

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

چھوٹے حروف میں :z content کو shared کے طور پر relabel کرتا ہے، اس لیے متعدد containers ایک ہی directory استعمال کر سکتے ہیں۔ بڑے حروف میں :Z اسے private اور unshared کے طور پر relabel کرتا ہے۔ یہ ایک container کے ساتھ مخصوص ہوتا ہے، اس لیے دوسرے container کو اسی path سے پڑھنے کی اجازت نہیں ملتی۔ جس directory کو sidecar یا backup container بھی استعمال کرتا ہو، اس کے لیے :z استعمال کریں۔ ایسی database directory کے لیے :Z استعمال کریں جس کی ملکیت ایک ہی container کے پاس ہو۔

Docker کی documentation میں ایک اہم warning ہے، کیونکہ relabel کارروائی recursive ہوتی ہے۔ /home یا /usr جیسی system directory کو :Z کے ساتھ bind-mount کرنے سے "آپ کی host machine ناقابلِ استعمال ہو سکتی ہے، اور آپ کو host machine کی files کو دستی طور پر relabel کرنا پڑ سکتا ہے"۔ ان suffixes کو صرف ان directories پر لگائیں جو آپ نے container کے لیے بنائی ہوں۔ انہیں کبھی system path پر نہ لگائیں۔

Compose میں suffix اسی string کے آخر میں لگتا ہے:

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

دو حدود سے آسانی سے مسئلہ پیدا ہو سکتا ہے۔ --mount flag، SELinux label set نہیں کر سکتا، اس لیے جب label درکار ہو تو -v استعمال کریں۔ Named volumes کے لیے suffix کی ضرورت نہیں ہوتی، کیونکہ Docker، /var/lib/docker/volumes کے تحت بنائی گئی directories کو خود label کرتا ہے۔

SELinux کو بند نہ کریں۔ صرف ایک منٹ کے test کے لیے sudo setenforce 0 استعمال کریں۔ اگر اس کے بعد container کام کرے تو مسئلہ label کا ہے، اور حل :z ہے۔ فوراً sudo setenforce 1 کے ذریعے اسے دوبارہ فعال کریں۔ Enterprise Linux میں bind mount پر permission denied کی دو الگ وجوہات ہو سکتی ہیں، جو container کے اندر سے یکساں نظر آتی ہیں۔ ایک وجہ SELinux label ہے۔ دوسری وجہ عام numeric user اور group ownership ہے، جسے حل کرنے کے لیے PUID اور PGID variables موجود ہیں۔ ls -lnZ ایک ہی line میں mode، numeric owner اور label دکھاتا ہے، اس لیے آپ معلوم کر سکتے ہیں کہ مسئلہ کس چیز کا ہے۔

فائر وال بند دکھائی دینے کے باوجود شائع کیا گیا port قابل رسائی کیوں ہوتا ہے؟

Firewalld، Rocky Linux اور AlmaLinux میں default firewall ہے۔ sudo systemctl is-active firewalld کے ذریعے تصدیق کریں کہ یہ چل رہا ہے۔ اب ایک port publish کریں اور دیکھیں کہ firewalld کے مطابق کون سا port کھلا ہے:

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 internet کے لیے کھلا ہے، لیکن firewall کچھ بھی رپورٹ نہیں کرتا۔

اس کی وجہ packet کا راستہ ہے۔ Firewalld کے zone rules اس traffic کو filter کرتے ہیں جو خود host کے لیے addressed ہو۔ Published port host کے لیے addressed نہیں ہوتا۔ Docker ایک destination NAT (network address translation) rule نصب کرتا ہے، جو packet کے host کے input path تک پہنچنے سے پہلے destination کو container کے address سے تبدیل کر دیتا ہے۔ اس لیے kernel packet کو مقامی طور پر deliver کرنے کے بجائے forward کرتا ہے۔ اس کے بعد Docker اپنے bridge interfaces کو firewalld کے docker نامی zone میں رکھتا ہے، جس کا target ACCEPT ہے، اور docker-forwarding نامی forwarding policy شامل کرتا ہے۔ یہ policy کسی بھی zone سے docker zone میں forwarding کی اجازت دیتی ہے۔ آپ کے zone rules packet کو دیکھ ہی نہیں پاتے۔

سب سے صاف حل کسی firewall rule کا محتاج نہیں۔ Publish کیے گئے port کے 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 واپس کرتا ہے، جبکہ کسی دوسری مشین سے بھیجی گئی وہی request اب connect نہیں ہوتی۔ -p argument میں host address نہ ہونے کی صورت میں service ہر interface پر publish ہوتی ہے۔ اس لیے خالی -p 8080:80 کو اس service کو public طور پر expose کرنے کا فیصلہ سمجھیں۔

جب کسی service کو کچھ addresses سے قابل رسائی اور دوسرے addresses سے ناقابل رسائی رکھنا ہو تو Docker آپ کے لیے ایک chain محفوظ رکھتا ہے۔ DOCKER-USER کو Docker کے اپنے accept rules سے پہلے process کیا جاتا ہے۔ اس لیے وہاں شامل کیا گیا rule Docker کے restart ہونے اور اپنی chains دوبارہ لکھنے کے بعد بھی برقرار رہتا ہے:

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

Interface کا نام ip route show default سے حاصل کریں، eth0 فرض نہ کریں، کیونکہ موجودہ EL images میں enp1s0 یا ens3 جیسے نام استعمال ہوتے ہیں۔ Rocky اور AlmaLinux میں iptables command، nftables کے اوپر compatibility layer ہے، اور Docker کی chains اس کے ذریعے دکھائی دیتی ہیں۔ اس طریقے سے شامل کیے گئے rules reboot کے بعد ختم ہو جاتے ہیں، جب تک آپ انہیں save نہ کریں۔ اس لیے rules کی تصدیق کے بعد انہیں systemd unit میں لکھ دیں۔

2025 میں released Docker Engine 28.0 نے اس سے متعلق ایک اور خامی بند کر دی۔ اب ایسے container ports تک direct routed access، جو کبھی publish نہیں کیے گئے، DOCKER chain میں block کیا جاتا ہے۔ اس تبدیلی کا published ports پر اثر نہیں پڑتا، اس لیے موجودہ versions پر بھی اوپر دی گئی تمام باتیں لاگو ہوتی ہیں۔ ایک عملی عادت اپنائیں: ہر sudo firewall-cmd --reload کے بعد published port دوبارہ test کریں۔ اگر اس نے جواب دینا بند کر دیا ہو تو sudo systemctl restart docker Docker کے rules دوبارہ نصب کرتا ہے۔

Ubuntu administrators کو یہی مسئلہ ایک مختلف tool کے ذریعے درپیش ہوتا ہے۔ اسی لیے published Docker ports، ufw rules کو نظر انداز کیوں کرتے ہیں۔ دونوں صورتوں میں NAT path ہی وجہ ہے۔ فرق صرف اس firewall کا ہے جو NAT path سے پہلے موجود ہوتا ہے۔

غیر-root صارف کو docker گروپ میں شامل کریں

ہر docker کمانڈ سے پہلے sudo لکھنا جلد ہی اکتاہٹ کا باعث بن جاتا ہے، اور docker گروپ اس کی ضرورت ختم کر دیتا ہے:

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

usermod -aG، /etc/group میں ترمیم کرتا ہے، لیکن موجودہ shell میں گروپس کی فہرست پہلے ہی load ہو چکی ہوتی ہے۔ اس لیے نئی گروپ رکنیت اس وقت تک لاگو نہیں ہوتی جب تک آپ نیا shell شروع نہ کریں۔ newgrp docker ایسا shell شروع کرتا ہے جس میں نیا گروپ شامل ہوتا ہے، تاکہ آپ فوراً جانچ کر سکیں۔ نئی SSH sessions میں یہ رکنیت خودکار طور پر شامل ہو جاتی ہے۔

واضح طور پر سمجھیں کہ یہ گروپ کون سے اختیارات دیتا ہے۔ رکنیت سے /var/run/docker.sock تک write access مل جاتا ہے۔ جو بھی اس socket سے رابطہ کر سکتا ہے، وہ daemon کو ایسا container شروع کرنے کے لیے کہہ سکتا ہے جو host filesystem کو mount کرے۔ ایک کمانڈ اس کا مطلب دکھاتی ہے:

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

یہ ایسی فائل پڑھتی ہے جسے صرف root پڑھ سکتا ہے، جبکہ اکاؤنٹ کے پاس sudo کے اختیارات نہیں ہوتے۔ Docker کی اپنی post-install دستاویزات بھی یہی کہتی ہیں: docker گروپ root کے مساوی privileges دیتا ہے۔ کسی اکاؤنٹ کو اس گروپ میں صرف اسی صورت شامل کریں جب آپ اسے sudo بھی دینے کے لیے تیار ہوں۔ اگر آپ نئے server پر accounts ترتیب دے رہے ہیں تو اس فیصلے کو بعد میں کرنے کے بجائے VPS پر کم سے کم اختیارات والی صارف ترتیب کے دیگر حصوں کے ساتھ کریں۔

Docker rootless mode بھی فراہم کرتا ہے، جس میں daemon غیر مراعات یافتہ صارف کے طور پر چلتا ہے۔ یہ installation کا الگ طریقہ ہے اور اس سے 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 میں expand کرتے ہیں۔ اس لیے EL 9 سسٹم CentOS 9 tree اور EL 10 سسٹم CentOS 10 tree استعمال کرتا ہے۔ sudo dnf repoinfo docker-ce-stable سے expansion کی تصدیق کریں اور Repo-baseurl لائن پڑھیں۔ اگر dnf metadata حاصل کرتے وقت Status code: 404 ظاہر ہو تو اس کا مطلب ہے کہ variable کسی point release میں expand ہوا ہے۔ /etc/yum.repos.d/docker-ce.repo میں bare major number استعمال کرنے سے یہ مسئلہ حل ہو جاتا ہے۔

کیا Docker اور podman ایک ہی سرور پر نصب کیے جا سکتے ہیں؟

Docker کی documentation podman اور runc کو متصادم packages قرار دیتی ہے اور Docker Engine نصب کرنے سے پہلے دونوں کو remove کرنے کی ہدایت دیتی ہے۔ اصل تصادم podman-docker package کا ہے، جو /usr/bin/docker کا مالک ہے اور ہر docker command کو podman command میں تبدیل کر دیتا ہے۔ یہ دیکھنے کے لیے rpm -qf "$(command -v docker)" چلائیں کہ اس path کا مالک کون سا package ہے۔ اگر output podman-docker سے شروع ہو تو podman جواب دے رہا ہے۔ دونوں engines کو ساتھ رکھنا Docker کا supported setup نہیں ہے، اس لیے اہم سرور پر ان میں سے ایک کا انتخاب کریں۔

bind mount پر میرے container کو permission denied کیوں ملتا ہے؟

Rocky Linux اور AlmaLinux پر SELinux پہلے سے enforcing ہوتا ہے۔ Containers container_t type کے طور پر چلتے ہیں اور صرف container_file_t label والی files تک رسائی حاصل کر سکتے ہیں۔ اس لیے آپ کی بنائی ہوئی directory پر غلط label ہوتا ہے اور مالک اور mode درست ہونے کے باوجود access denied ملتا ہے۔ Host path پر ls -ldZ اور sudo ausearch -m avc -ts recent سے اس کی تصدیق کریں۔ sudo ausearch -m avc -ts recent avc: denied کو دو مختلف contexts کے ساتھ دکھاتا ہے۔ Containers کے درمیان shared content کے لیے volume argument میں :z شامل کریں، یا کسی ایک container کے لیے private content پر :Z استعمال کریں۔ :Z کو کبھی /home یا /usr کی طرف مت لگائیں، کیونکہ relabel recursive ہوتا ہے اور host کو نقصان پہنچا سکتا ہے۔

کیا container port publish کرنے کے لیے firewalld میں port کھولنا ضروری ہے؟

نہیں، اور یہی مسئلہ ہے۔ Docker کا NAT rule packet کے host کے input path تک پہنچنے سے پہلے destination address تبدیل کر دیتا ہے، اس لیے firewalld کے zone rules اسے inspect نہیں کرتے۔ Docker اپنے bridges کو docker نامی firewalld zone میں بھی شامل کرتا ہے، جس کا target ACCEPT ہے۔ -p 8080:80 کے ساتھ شروع کیا گیا container internet سے قابل رسائی ہوتا ہے، جبکہ sudo firewall-cmd --list-ports کچھ بھی output نہیں کرتا۔ جب صرف 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 کے ذریعے ایسے account سے root-only file پڑھ سکتا ہے جس کے پاس sudo rights نہیں ہیں۔ Docker کی post-install documentation بھی یہی equivalence بیان کرتی ہے۔ صرف ان accounts کو شامل کریں جنہیں آپ sudo کے برابر پہلے ہی trusted سمجھتے ہوں۔ Shared یا service accounts کے لیے sudo docker استعمال کرتے رہیں۔ جب unprivileged user کے تحت containers چلانے ہوں تو rootless mode متبادل ہے۔ یہ setting نہیں بلکہ الگ install path ہے۔