VPS पर Podman बनाम Docker: मुख्य अंतर और क्या चुनें
VPS पर Podman और Docker के बीच का अंतर जानें। Podman बिना daemon और rootless चलता है। यह लेख compose files, quadlets, ports और volume ownership की समस्याओं को हल करता है।
Podman और Docker के बीच वास्तविक अंतर क्या है
Podman और Docker एक VPS पर समान OCI (open container initiative) images चलाते हैं, इसलिए चुनाव इस बात पर निर्भर नहीं करता कि आप कौन सा software चला सकते हैं। अंतर process model में है। Docker एक root daemon चलाता है जो हर container का स्वामी होता है, और docker command एक छोटा client है जो उस daemon से काम करने के लिए कहता है। Podman में कोई daemon नहीं होता: podman run container को उसे call करने वाली process की child process के रूप में, आपके अपने unprivileged user के अंतर्गत शुरू करता है।
बाकी सब कुछ इसी एक तथ्य से निकलता है। Auto-start daemon के बजाय systemd का काम बन जाता है। Volume ownership एक user namespace के माध्यम से गुजरती है, इसलिए host पर ls -l के साथ जो owner आपको दिखता है, वह container को दिखने वाला owner नहीं होता। 1024 से नीचे के ports तब तक bind होने से मना कर देते हैं जब तक आप kernel setting नहीं बदलते। docker CLI (command line interface) एक wrapper के माध्यम से काम करना जारी रखता है, ठीक उस बिंदु तक जहाँ किसी चीज़ को Docker socket की आवश्यकता होती है।
कोई डेमन नहीं: कंटेनर शुरू करने पर वास्तव में क्या चलता है
Docker होस्ट पर, pstree -a में dockerd रूट के रूप में, उसके बगल में containerd, और प्रत्येक चल रहे कंटेनर के लिए एक containerd-shim-runc-v2 दिखाई देता है। आपका एप्लिकेशन उस शिम (shim) का चाइल्ड प्रोसेस होता है, और शिम स्वयं PID 1 का चाइल्ड होता है। कंटेनर का उस शेल से कोई संबंध नहीं होता जिसने उसे शुरू किया था। यदि आप डेमन को रोकते हैं, तो आप बॉक्स पर मौजूद प्रत्येक कंटेनर के लिए कंट्रोल प्लेन खो देते हैं, और डिफ़ॉल्ट live-restore सेटिंग बंद होने पर, systemctl restart docker आपके कंटेनरों को भी रीस्टार्ट कर देता है।
Podman में ऐसी कोई समकक्ष प्रक्रिया नहीं है। एक कंटेनर शुरू करने पर आपको एक conmon (कंटेनर मॉनिटर) प्रोसेस मिलता है जो कंटेनर की मुख्य प्रक्रिया को होल्ड करता है, और इसका स्वामित्व उस उपयोगकर्ता के पास होता है जिसने कमांड चलाई है।
podman run -d --name web -p 8080:80 docker.io/library/caddy:2
ps -o user,pid,ppid,args -C conmon
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080ps को आपके लॉगिन उपयोगकर्ता के रूप में चल रहे conmon को सूचीबद्ध करना चाहिए, न कि रूट के रूप में, और curl को 200 प्रिंट करना चाहिए। चूंकि कोई केंद्रीय सेवा कंटेनर की मालिक नहीं होती, इसलिए sudo apt upgrade podman पहले से चल रही किसी भी चीज़ को नहीं रोकता है, और एक कंटेनर के मॉनिटर के क्रैश होने से दूसरे कंटेनर प्रभावित नहीं होते हैं।
डेमन न होने की एक कीमत भी चुकानी पड़ती है। रीबूट के बाद आपके कंटेनरों को कोई स्वतः शुरू नहीं करता है। Docker का --restart=always एक वादा है जिसे डेमन बूट के समय पूरा करता है, और Podman इसे systemd के साथ बदल देता है, जिसके लिए नीचे दिया गया quadlet सेक्शन है।
सॉकेट इस कहानी का दूसरा हिस्सा है। /var/run/docker.sock एक रूट-स्वामित्व वाला API (एप्लिकेशन प्रोग्रामिंग इंटरफ़ेस) एंडपॉइंट है, और जो भी प्रोसेस इसमें लिख सकता है, वह एक प्रिविलेज्ड कंटेनर शुरू कर सकता है जो होस्ट फाइलसिस्टम को माउंट करता है। किसी उपयोगकर्ता को docker ग्रुप में जोड़ने का मतलब है उसे एक धीमे रास्ते से रूट एक्सेस देना, जिसके बारे में प्रत्येक सर्विस अकाउंट को केवल आवश्यक एक्सेस देना के साथ पढ़ना उचित है। Podman तब तक कोई सॉकेट एक्सपोज़ नहीं करता जब तक आप इसके लिए न कहें, और जो सॉकेट आपको मिलता है वह /run/user/<uid>/podman/podman.sock पर एक एकल उपयोगकर्ता का होता है।
Ubuntu 24.04 पर Podman इंस्टॉल करें और पुष्टि करें कि rootless मोड सक्रिय है
sudo apt update
sudo apt install -y podman uidmap
podman --version
podman info | grep -i rootlessuidmap पैकेज newuidmap और newgidmap प्रदान करता है। ये setuid हेल्पर्स हैं जो एक सामान्य उपयोगकर्ता को subordinate ID की एक रेंज प्राप्त करने की अनुमति देते हैं, और इनके बिना rootless containers शुरू नहीं होते हैं। podman info को rootless: true प्रिंट करना चाहिए।
Ubuntu 24.04 में Podman 4.9 और Debian 13 में Podman 5.x शामिल है, जिसे अगस्त 2026 में जांचा गया था। यह अंतर महत्वपूर्ण है, क्योंकि quadlet फाइलों को 4.4 या उससे नए संस्करण की आवश्यकता होती है और .pod quadlet फाइलों को 5.0 की आवश्यकता होती है। अपस्ट्रीम डॉक्यूमेंटेशन से कोई उदाहरण कॉपी करने से पहले podman --version चलाएं।
प्रत्येक rootless उपयोगकर्ता को एक subordinate ID रेंज की आवश्यकता होती है:
grep "$USER" /etc/subuid /etc/subgidUbuntu पर adduser द्वारा बनाया गया उपयोगकर्ता स्वचालित रूप से एक रेंज प्राप्त कर लेता है। useradd -M या किसी कॉन्फ़िगरेशन टूल द्वारा बनाया गया उपयोगकर्ता अक्सर ऐसा नहीं करता है, और विफलता का संदेश यही बताता है:
Error: cannot find UID/GID for user deploy: no subuid ranges found for user "deploy" in /etc/subuid - check rootless mode in man pages.एक रेंज असाइन करें, फिर उस उपयोगकर्ता के स्टोरेज को रीसेट करें ताकि नई मैपिंग का उपयोग किया जा सके:
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 deploy
podman system migrateपहली बार चलाने पर एक और आश्चर्य: Podman Docker Hub को डिफ़ॉल्ट नहीं मानता है। एक छोटा इमेज नाम /etc/containers/registries.conf में unqualified-search-registries के विरुद्ध रिज़ॉल्व किया जाता है, और बिना टर्मिनल वाले स्क्रिप्ट में pull प्रक्रिया short-name resolution enforced but cannot prompt without a TTY के साथ विफल हो जाती है। हर बार पूरा नाम लिखें। nginx के बजाय docker.io/library/nginx:1.27 का उपयोग करें।
रेंटेड सर्वर पर rootless containers वास्तव में आपको क्या सुरक्षा देते हैं
एक rootless container एक user namespace के अंदर चलता है। यह kernel का एक फीचर है जो किसी process को user IDs का अपना निजी मैप देता है। namespace के अंदर, container का superuser UID (user ID) 0 होता है। बाहर, आपके VPS पर, वही process आपके सामान्य login user के रूप में होती है। container के अंदर का root, host पर root नहीं होता है।
यह इस सुरक्षा का वास्तविक दायरा है। कोई image जो root के रूप में चलने पर जोर देती है, कोई web application जिसमें remote code execution बग है, या कोई ऐसा escape जो बाहर UID 0 होने पर निर्भर करता है: ये सभी अंततः मशीन की अनुमतियों के बजाय आपके unprivileged user की अनुमतियों तक ही सीमित रह जाते हैं। rootless यह नहीं करता कि वह आपको kernel बग्स से बचाए, और यह आपकी अपनी फाइलों की सुरक्षा भी नहीं करता है, क्योंकि escaped process आपके रूप में चल रही होती है और वह सब कुछ पढ़ सकती है जिसे आप पढ़ सकते हैं। isolated की जा रही इकाई का महत्व UID मैपिंग जितना ही है, जिसे एक FreeBSD jail, जो एक पूरे userland को लपेटता है जिसे आप एक छोटी मशीन की तरह प्रबंधित करते हैं में देखना आसान है, बजाय इसके कि registry से खींची गई layered image में।
Docker भी rootless चल सकता है। dockerd-rootless-setuptool.sh install प्रति-उपयोगकर्ता daemon सेट करता है और यह अच्छी तरह से काम करता है। अंतर यह है कि डिफ़ॉल्ट रूप से क्या सेट है। Podman के साथ आपको बिना मांगे rootless मिलता है, इसलिए आपकी पहली विफलता एक ऐसा container होता है जो port 80 को bind नहीं कर सकता, बजाय उस service के जो चुपचाप दो साल तक root के रूप में चलती रही।
मेरे वॉल्यूम फाइलों का मालिक UID 100999 क्यों है?
यह उसी user namespace के कारण है। Container का UID 0 आपके host के UID पर map होता है। Container का UID 1 आपके subuid range की पहली ID पर map होता है, और वहाँ से गिनती आगे बढ़ती है। 100000 से शुरू होने वाली range के साथ, container का UID 1000 host पर 100999 के रूप में दिखाई देता है।
mkdir -p "$PWD/data"
podman run --rm --user 1000 -v "$PWD/data:/data" docker.io/library/alpine:3 sh -c 'id -u; touch /data/f'
ls -ln "$PWD/data"Container 1000 प्रिंट करता है। Host की listing में मालिक 100999 दिखता है, क्योंकि 100000 में 1000 जोड़कर 1 घटाने पर 100999 आता है। कुछ भी खराब नहीं हुआ है, और एक साधारण chown इसे ठीक नहीं करेगा, क्योंकि आपका unprivileged user namespace के बाहर फाइल का मालिकाना हक (ownership) नहीं बदल सकता।
इससे बचने के चार तरीके हैं:
podman unshare chown 1000:1000 "$PWD/data"उसी user namespace के अंदर chown चलाता है, जहाँ संख्याओं का वही अर्थ होता है जो container के लिए है।-v "$PWD/data:/data:U"Podman से source directory का मालिकाना हक आपके लिए ठीक करने को कहता है। इसे किसी नई directory पर इस्तेमाल करें, न कि उस डेटा पर जिसकी आपको परवाह है।--userns=keep-idआपके host UID को container के अंदर उसी UID पर map करता है, ताकि नई फाइलें आपके नाम से बनें।-v appdata:/dataजैसा एक named volume इस समस्या को ही खत्म कर देता है, क्योंकि Podman इसे आपके अपने storage के अंदर सही मालिकाना हक के साथ बनाता है।
यदि आपने Docker में इससे संघर्ष किया है, तो यह एक स्तर ऊपर वही समस्या है। PUID और PGID variables जो कई images expose करती हैं उस UID को सेट करते हैं जिसका उपयोग container के अंदर process करती है, और rootless Podman के तहत उस UID को दूसरी बार map किया जाता है। Rootless container के अंदर PUID=1000 अभी भी host पर 100999 के मालिकाना हक वाली फाइलें ही लिखता है। उस दूसरी mapping को ध्यान में रखकर संख्याएं चुनें, या डेटा को named volume में ले जाएं और इसके बारे में सोचना बंद करें।
mounts पर दो और बातें। Fedora और RHEL के उदाहरणों में दिखने वाले :z और :Z flags SELinux relabel विकल्प हैं, और Ubuntu AppArmor का उपयोग करता है, इसलिए वहां इनका कोई प्रभाव नहीं पड़ता। Rootless Podman ऐसी host directory को भी mount नहीं कर सकता जिसे आपका user पढ़ नहीं सकता, जो कि एक कमी के बजाय सुरक्षा का उद्देश्य है।
Rootless Podman port 80 को publish करने से मना क्यों करता है?
क्योंकि 1024 से नीचे के port को bind करने के लिए ऐसे विशेषाधिकार (privilege) की आवश्यकता होती है जो आपके user के पास नहीं है। त्रुटि (error) में ही समाधान का नाम दिया गया है:
Error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission deniedदो समाधान काम करते हैं। पूरे host के लिए threshold को कम करें:
echo 'net.ipv4.ip_unprivileged_port_start=80' | sudo tee /etc/sysctl.d/99-podman.conf
sudo sysctl --system
sysctl net.ipv4.ip_unprivileged_port_startअंतिम command को 80 वापस echo करना चाहिए। यह स्पष्ट रहें कि वह setting क्या करती है: मशीन पर मौजूद हर user अब 80 और 443 को bind कर सकता है, न कि केवल वह user जो containers चला रहा है। एक single-admin VPS पर यह एक स्वीकार्य समझौता है। ऐसी मशीन पर जहाँ अन्य लोगों के accounts हैं, यह उचित नहीं है। दूसरा समाधान 8080 पर publish करना और सामने एक reverse proxy रखना है, जो कि वही स्थान है जहाँ आप certbot द्वारा nginx पर जारी और नवीनीकृत किए गए certificates चाहते हैं।
Rootless publishing यह भी बदल देता है कि आपका application क्या देखता है। Podman 4.x डिफ़ॉल्ट रूप से rootlesskit port handler के साथ slirp4netns का उपयोग करता है, और forwarded connections एक rewritten source address के साथ आते हैं, इसलिए access log हर visitor को 10.0.2.100 के रूप में record करता है। Podman 5.0 ने डिफ़ॉल्ट को pasta में बदल दिया, जो वास्तविक client address को बनाए रखता है। 4.x पर, --network slirp4netns:port_handler=slirp4netns throughput में कुछ कमी की कीमत पर true source address को पुनर्स्थापित (restore) करता है।
यहाँ एक अच्छा आश्चर्य है। Rootless published port एक सामान्य listening socket है जिसका स्वामित्व एक सामान्य process के पास होता है, इसलिए आपके firewall के input rules इस पर लागू होते हैं। Docker ports को NAT (network address translation) rules और अपने स्वयं के forwarding accepts लिखकर publish करता है, और यही कारण है कि एक published Docker port उस ufw rule को अनदेखा कर देता है जिसे आप ब्लॉक मान रहे थे। Rootful Podman समान plumbing का उपयोग करता है और उसी जाल (trap) को विरासत में प्राप्त करता है। Rootless ऐसा नहीं करता है।
क्या मेरे Docker Compose files Podman के अंतर्गत काम करते हैं?
ज्यादातर, दो अलग-अलग तरीकों से। पहला podman-compose है, जो एक अलग implementation है जो उसी file को पढ़ता है और Podman CLI को चलाता है:
sudo apt install -y podman-compose
podman-compose up -d
podman psदूसरा तरीका असली Docker Compose का उपयोग करना है जो प्रति-उपयोगकर्ता (per-user) socket के माध्यम से Podman के Docker-compatible API से बात करता है:
systemctl --user enable --now podman.socket
export DOCKER_HOST="unix:///run/user/$(id -u)/podman/podman.sock"
docker compose up -d
podman psdocker compose ps और podman ps को एक ही containers की सूची दिखानी चाहिए, क्योंकि वे केवल एक ही सेट हैं। Name resolution भी काम करता है: Podman का डिफ़ॉल्ट network backend, netavark, aardvark-dns चलाता है, इसलिए user-defined network पर मौजूद containers एक-दूसरे को नाम से ढूँढ लेते हैं।
सीमाएं वास्तविक हैं। जो कुछ भी /var/run/docker.sock को mount करता है, उसे Podman socket की ओर इंगित करना होगा या हटाना होगा। network_mode: host user namespace के अंतर्गत अलग तरह से व्यवहार करता है। depends_on के साथ condition: service_healthy का समर्थन podman-compose के विभिन्न versions में असमान है। restart: always अपने आप reboot के बाद सुरक्षित नहीं रहता, जिसे अगला section ठीक करता है। Compose अभी भी एक ही file में multi-container stack को वर्णित करने का एक अच्छा तरीका है, और Podman के अंतर्गत यह एक translation layer है। जिस stack को आप वर्षों तक बनाए रखना चाहते हैं, उसे quadlets में बदलें और दो के बजाय एक abstraction बनाए रखें।
Pods: वह विचार जिसका Docker के पास कोई उत्तर नहीं है
Pod कंटेनरों का एक समूह है जो एक ही network namespace साझा करते हैं। Podman उस namespace को खुला रखने के लिए एक छोटा infra कंटेनर शुरू करता है, और फिर सदस्य एक-दूसरे तक 127.0.0.1 पर पहुँचते हैं। इसमें किसी user-defined network या service discovery की आवश्यकता नहीं होती है।
podman pod create --name app -p 8080:80
podman run -d --pod app --name app-cache docker.io/library/redis:7
podman run -d --pod app --name app-web docker.io/library/nginx:1.27
podman pod ps
podman ps --podpodman pod ps को pod Running को तीन कंटेनरों के साथ दिखाना चाहिए, जिसमें infra कंटेनर भी शामिल है। web कंटेनर अब Redis तक app-cache:6379 के बजाय 127.0.0.1:6379 पर पहुँचता है। साझा namespace से दो नियम निकलते हैं: ports को pod पर publish करें न कि किसी सदस्य पर, और कोई भी दो सदस्य एक ही port पर listening नहीं हो सकते।
यह Kubernetes मॉडल है, और Podman इसी का अनुसरण करता है। podman kube generate app > app.yaml चल रहे कंटेनरों से एक Kubernetes manifest लिखता है (पुराने packages में इसे podman generate kube कहा जाता है), और podman kube play app.yaml इसे किसी अन्य host पर फिर से बनाता है। Quadlet में एक .kube unit type है जो ऐसी file को systemd service के रूप में चलाता है। यह सेवाओं को समूहबद्ध करने का वास्तव में एक अलग तरीका है, और यदि आपके भविष्य में कहीं भी Kubernetes है, तो Podman चुनने का यह सबसे मजबूत कारण है।
बिना डेमन के ऑटो-स्टार्ट: quadlet units
Quadlet एक systemd जनरेटर है। यह बूट के समय कंटेनर का वर्णन करने वाली एक छोटी फाइल को वास्तविक systemd सर्विस में बदल देता है। फाइलें rootless यूजर के लिए ~/.config/containers/systemd/ में, या root के लिए /etc/containers/systemd/ में रखी जाती हैं।
~/.config/containers/systemd/caddy.container:
[Unit]
Description=Caddy web server
After=network-online.target
[Container]
Image=docker.io/library/caddy:2
ContainerName=caddy
PublishPort=8080:80
Volume=caddy-data.volume:/data
Environment=TZ=UTC
AutoUpdate=registry
[Service]
Restart=always
MemoryMax=512M
[Install]
WantedBy=default.target~/.config/containers/systemd/caddy-data.volume लगभग खाली हो सकता है, क्योंकि सेक्शन हेडर ही वॉल्यूम बनाता है:
[Volume]systemctl --user daemon-reload
systemctl --user start caddy
systemctl --user status caddy
journalctl --user -u caddy -n 50सर्विस का नाम फाइल के नाम से आता है: caddy.container बदलकर caddy.service हो जाता है। systemctl --user enable caddy न चलाएं। जनरेट की गई यूनिट्स को इनेबल नहीं किया जा सकता है, और systemd Failed to enable unit: Unit /run/user/1000/systemd/generator/caddy.service is transient or generated. का उत्तर देता है। [Install] सेक्शन ही वह है जो बूट पर कंटेनर को शुरू करता है, और daemon-reload वह है जो फाइल को एडिट करने के बाद यूनिट को फिर से जनरेट करता है।
अब वह सेटिंग जो लगभग सभी को परेशान करती है:
sudo loginctl enable-linger deploy
loginctl show-user deploy --property=LingerLinger=yes की अपेक्षा करें। Linger के बिना, जब आपका अंतिम SSH कनेक्शन बंद होता है तो systemd पूरे यूजर सेशन को समाप्त कर देता है, इसलिए हर rootless कंटेनर उसके साथ रुक जाता है और उनमें से कोई भी बूट पर वापस नहीं आता है। जो कंटेनर लॉग आउट करने पर गायब हो जाते हैं, वे हमेशा इसी कारण से होते हैं।
चूंकि कंटेनर एक साधारण सर्विस यूनिट की मुख्य प्रक्रिया है, इसलिए systemd के अपने नियंत्रण सीधे लागू होते हैं। [Service] सेक्शन में MemoryMax= और CPUQuota= बिल्कुल वैसे ही व्यवहार करते हैं जैसे वे systemd के साथ कैप की गई किसी अन्य सर्विस के लिए करते हैं। इसके लिए cgroup v2 (कंट्रोल ग्रुप वर्जन 2) की आवश्यकता होती है, जिसका उपयोग Ubuntu 22.04 के बाद से डिफ़ॉल्ट रूप से कर रहा है। podman info | grep -i cgroup के साथ पुष्टि करें।
अपडेट्स के लिए एक मैचिंग मैकेनिज्म है। AutoUpdate=registry और systemctl --user enable --now podman-auto-update.timer एक ही टैग पर नए इमेज के लिए रजिस्ट्री की जांच करते हैं, यूनिट को रीस्टार्ट करते हैं, और यदि नया कंटेनर शुरू होने में विफल रहता है तो पिछली इमेज पर रोलबैक कर देते हैं। यह देखने के लिए कि यह क्या बदलेगा, पहले podman auto-update --dry-run चलाएं। पुराना podman generate systemd कमांड अभी भी मौजूद है और इसे डेप्रिकेट कर दिया गया है, इसलिए किसी भी नई चीज़ के लिए quadlets लिखें।
जहाँ docker alias काम करता है, और जहाँ नहीं
sudo apt install -y podman-docker
sudo touch /etc/containers/nodocker
docker pspodman-docker एक /usr/bin/docker wrapper इंस्टॉल करता है जो Podman को कॉल करता है। nodocker फाइल के बिना, हर कॉल पहले Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. प्रिंट करती है। यह wrapper उन commands को कवर करता है जिन्हें आप दिन भर टाइप करते हैं: run, ps, logs, exec, build, pull, push, inspect, cp, volume, network।
जो चीजें स्थानांतरित नहीं होती हैं, उनकी सूची छोटी और अधिक स्पष्ट है। Swarm mode का कोई समकक्ष नहीं है, इसलिए Swarm stack के लिए कोई स्थान नहीं है। जो tools Docker socket से बात करते हैं, उन्हें Podman socket को export करने की आवश्यकता होती है, और कुछ अभी भी अंतर को पहचान लेते हैं; Traefik का Docker provider तब काम करता है जब उसे /run/user/<uid>/podman/podman.sock पर पॉइंट किया जाता है, जबकि Watchtower का कोई स्थान नहीं है, क्योंकि podman auto-update वह काम करता है। स्टोरेज अलग है, इसलिए Podman उन images को नहीं देख सकता जिन्हें आपने पहले ही Docker के साथ pull किया है, और एक व्यस्त Docker host पर podman images खाली शुरू होता है।
चलते हुए stack को migrate करना, चरण-दर-चरण
- उस unprivileged user को बनाएँ या चुनें जो containers का स्वामी होगा, और पुष्टि करें कि उसके पास
/etc/subuidमें एक range है। - registry से आई किसी भी चीज़ को fully qualified names का उपयोग करके फिर से pull करें। Podman का अपना image store होता है और यह Docker के store को नहीं पढ़ेगा।
- स्थानीय रूप से बनी images को
docker save app:1.4 | podman loadके साथ स्थानांतरित करें। - Docker container को रोकें,
/var/lib/docker/volumes/<name>/_dataसे प्रत्येक volume की सामग्री को copy करें, फिरpodman unshare chown -R 1000:1000 <path>के साथ ownership ठीक करें। - port के प्रश्न को हल करें: reverse proxy के पीछे 1024 से ऊपर publish करें, या
net.ipv4.ip_unprivileged_port_startसेट करें। - प्रति container एक quadlet file लिखें,
systemctl --user daemon-reloadचलाएँ, और प्रत्येक service को start करें। sudo loginctl enable-linger <user>चलाएँ, VPS को reboot करें, वापस login करें और जाँचें किpodman psमें सभी services फिर से दिखाई दे रही हैं।
दोनों engines के बीच कुछ भी साझा नहीं होता है: अलग image storage और अलग networks। इसलिए आप migrate करते समय दोनों को एक साथ चला सकते हैं, और वे केवल एक host port number के लिए संघर्ष कर सकते हैं। एक service को move करें, एक दिन तक उसकी निगरानी करें, फिर अगली service को move करें।
Podman बनाम Docker: आपके VPS के लिए कौन सा बेहतर है?
यदि आपका stack उन compose files में है जिन्हें अन्य लोग भी maintain करते हैं, या यदि आप ऐसे tooling पर निर्भर हैं जो Docker socket से बात करता है, तो Docker का ही उपयोग करें। दूसरों द्वारा लिखे गए कोड के साथ compatibility एक वास्तविक विशेषता है, और Docker में यह अधिक है। जिन टीमों के laptops पर Docker चलता है, उन्हें production में भी वही engine चलाने से ठोस लाभ मिलता है।
यदि आपका VPS कुछ ऐसी services चलाता है जिन्हें आप पूरी तरह से नियंत्रित करते हैं, या यदि आप चाहते हैं कि प्रत्येक application अपने स्वयं के unprivileged user के अंतर्गत चले और box पर कोई docker group न हो, तो Podman पर स्विच करें। Distribution alignment भी मायने रखती है: RHEL और इसके rebuilds में Podman को supported engine के रूप में ship किया जाता है, इसलिए उन systems पर Podman का उपयोग करने में कम समस्याएं आती हैं। यदि आप फिर भी उन hosts पर Docker चाहते हैं, तो Rocky Linux और AlmaLinux पर dnf मार्ग की शुरुआत podman-docker wrapper को हटाने से होती है, जो वहां पहले से ही docker command का स्वामी है। यदि आप पहले से ही बाकी सब कुछ systemd units के साथ supervise करते हैं, तो quadlets आपको एक नए उपकरण के बजाय एक खोए हुए हिस्से के मिलने जैसा महसूस होगा।
एक मध्यम विकल्प का उल्लेख करना उचित है। Rootful Podman काफी हद तक Docker की तरह व्यवहार करता है, wrapper के माध्यम से docker command को बनाए रखता है, और फिर भी हमेशा चलने वाले daemon को हटा देता है। यह rootless सुविधा को छोड़ देता है, जो कि वह हिस्सा है जो आपकी सुरक्षा स्थिति को बदलता है, इसलिए इसे केवल एक पड़ाव के रूप में देखें।
यदि आप अभी भी अपना पहला container host बना रहे हैं, तो एक नए VPS पर Docker सेटअप और हार्डनिंग मार्ग छोटा रास्ता है, और वह ज्ञान व्यर्थ नहीं जाएगा। Images और volumes दोनों engines के अंतर्गत समान objects हैं, इसलिए बाद में बदलाव करने पर केवल आपकी services की supervision का तरीका बदलेगा, बाकी बहुत कम चीजें बदलेंगी।
FAQ
क्या Podman, Docker का पूर्ण विकल्प (drop-in replacement) है?
आपके द्वारा टाइप की जाने वाली commands के लिए, यह काफी हद तक वैसा ही है। podman-docker इंस्टॉल करने पर आपको एक /usr/bin/docker wrapper मिलता है, और run, ps, build, logs तथा exec उसी तरह काम करते हैं। यह daemon का विकल्प नहीं है। Swarm का कोई समकक्ष नहीं है, जो tools /var/run/docker.sock से connect होते हैं, उन्हें per-user Podman socket की ओर निर्देशित करना होगा, और Docker द्वारा pull की गई images Podman को दिखाई नहीं देतीं क्योंकि दोनों का storage अलग-अलग होता है।
SSH से logout करने पर मेरे rootless Podman containers क्यों रुक जाते हैं?
क्योंकि जब आपका अंतिम login session बंद होता है, तो systemd उस user session और उसके साथ चल रही हर user service को रोक देता है। sudo loginctl enable-linger <user> चलाएँ, फिर जाँचें कि loginctl show-user <user> --property=Linger, Linger=yes print करता है या नहीं। Linger उस user के systemd instance को बिना किसी active session के भी चालू रखता है, जो reboot के बाद containers को फिर से start करने के लिए भी आवश्यक है।
मेरे volume में files का owner UID 100999 क्यों है?
Rootless Podman, container UID 0 को आपके host user से map करता है, और फिर container UID 1 व उसके ऊपर के UID को आपकी subuid range पर map करता है। यदि range 100000 से शुरू होती है, तो container UID 1000, host पर 100999 बन जाता है। इसे namespace के अंदर podman unshare chown 1000:1000 /path/to/data से ठीक करें, पहली बार run करते समय :U flag के साथ mount करें, या --userns=keep-id का उपयोग करें ताकि container UIDs आपके स्वयं के UIDs से मेल खा सकें।
क्या मैं Podman के साथ docker-compose.yml का उपयोग जारी रख सकता हूँ?
हाँ, दो तरीकों से। podman-compose फाइल को read करता है और सीधे Podman CLI को चलाता है। या फिर systemctl --user enable --now podman.socket के साथ compatibility socket को enable करें, DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock set करें, और इसके विरुद्ध वास्तविक docker compose चलाएँ। network_mode: host पर, Docker socket को mount करने वाली services पर, और restart: always पर कुछ कठिनाइयाँ आ सकती हैं, जिसे reboot के बाद चालू रखने के लिए quadlet unit और linger की आवश्यकता होती है।
क्या rootless वास्तव में containers को अधिक सुरक्षित बनाता है?
यह एक विशिष्ट जोखिम को हटा देता है: यदि कोई process rootless container से बाहर निकलती है, तो उसके पास root के बजाय आपके unprivileged user की permissions होती हैं। यह एक महत्वपूर्ण सुरक्षा है, और यही कारण है कि root-equivalent docker group का rootless Podman में कोई समकक्ष नहीं है। यह kernel vulnerabilities को नहीं रोकता है, और यह उन files की सुरक्षा नहीं करता जिन्हें आपका user पढ़ सकता है, इसलिए किसी भी server पर की जाने वाली अन्य hardening प्रक्रियाएँ जारी रखें।