VPS पर Podman बनाम Docker: मुख्य अंतर और क्या चुनें
Podman daemon-less और rootless आर्किटेक्चर पर काम करता है। यह लेख बताता है कि VPS पर 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 कंटेनर शुरू नहीं होते हैं। 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 के आधार पर रिज़ॉल्व किया जाता है, और बिना टर्मिनल वाले स्क्रिप्ट में पुल करने पर short-name resolution enforced but cannot prompt without a TTY के साथ विफलता मिलती है। हर बार पूरा नाम लिखें। nginx के बजाय docker.io/library/nginx:1.27 का उपयोग करें।
रेंटेड सर्वर पर rootless containers का वास्तविक लाभ
Rootless container एक user namespace के भीतर चलता है, जो kernel का एक ऐसा feature है जो process को user IDs का अपना निजी map प्रदान करता है। Namespace के भीतर container का superuser, UID (user ID) 0 होता है। बाहर, आपके VPS पर, वही process आपका सामान्य login user होता है। Container के भीतर का root, host पर root नहीं होता।
यही इस सुरक्षा का वास्तविक लाभ है। कोई image जो root के रूप में चलने की जिद करती है, कोई web application जिसमें remote code execution bug है, या कोई escape जो बाहर UID 0 होने पर निर्भर करता है: ये सभी अंततः machine की permissions के बजाय आपके unprivileged user की permissions तक ही सीमित रह जाते हैं। Rootless यह नहीं करता कि वह आपको kernel bugs से बचाए, और यह आपकी अपनी files की सुरक्षा भी नहीं करता, क्योंकि escaped process आपके user के रूप में चल रही होती है और वह सब कुछ पढ़ सकती है जिसे आप पढ़ सकते हैं।
Docker भी rootless चल सकता है। dockerd-rootless-setuptool.sh install प्रति-user daemon को setup करता है और यह अच्छी तरह काम करता है। अंतर केवल इस बात का है कि default configuration किस ओर इशारा करती है। Podman के साथ आपको बिना मांगे rootless मिलता है, इसलिए आपकी पहली विफलता एक ऐसा container होती है जो port 80 को bind नहीं कर पाता, बजाय उस service के जो चुपचाप दो साल तक root के रूप में चलती रही।
मेरी volume files का owner UID 100999 क्यों है?
यह उसी user namespace के कारण है। Container का UID 0 आपके host के UID पर map होता है। Container का UID 1 आपकी subuid range की पहली ID पर map होता है, और वहाँ से गिनती आगे बढ़ती है। यदि range 100000 से शुरू होती है, तो 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 में owner 100999 दिखता है, क्योंकि 100000 जमा 1000 घटा 1 बराबर 100999 होता है। कुछ भी खराब नहीं है, और एक साधारण chown इसे ठीक नहीं करेगा, क्योंकि आपका unprivileged user namespace के बाहर file ownership को बदल ही नहीं सकता।
इससे निपटने के चार तरीके हैं:
podman unshare chown 1000:1000 "$PWD/data"को उसी user namespace के अंदर चलाएं, जहाँ numbers का वही मतलब होता है जो container के लिए है।-v "$PWD/data:/data:U"Podman से source directory की ownership को आपके लिए ठीक करने के लिए कहता है। इसे किसी नई directory पर इस्तेमाल करें, न कि उस data पर जिसकी आपको परवाह है।--userns=keep-idआपके host UID को container के अंदर उसी UID पर map करता है, ताकि नई files आपके नाम पर ही बनें।-v appdata:/dataजैसी named volume इस समस्या को ही खत्म कर देती है, क्योंकि Podman इसे आपके अपने storage के अंदर सही ownership के साथ बनाता है।
यदि आपने Docker में इससे संघर्ष किया है, तो यह एक स्तर ऊपर वही समस्या है। PUID और PGID variables जिन्हें कई images expose करती हैं उस UID को set करते हैं जिसका उपयोग container के अंदर process करती है, और rootless Podman के तहत उस UID को दूसरी बार map किया जाता है। Rootless container के अंदर PUID=1000 अभी भी host files को 100999 के owner के साथ ही लिखेगा। उन numbers को इस दूसरी mapping को ध्यान में रखकर चुनें, या data को named volume में ले जाएं और इसके बारे में सोचना बंद करें।
mounts पर दो और बातें। Fedora और RHEL के उदाहरणों में जो :z और :Z flags आप देखते हैं, वे SELinux relabel options हैं, और Ubuntu AppArmor का उपयोग करता है, इसलिए वे वहाँ काम नहीं करते। Rootless Podman ऐसी host directory को mount नहीं कर सकता जिसे आपका user पढ़ नहीं सकता, यह एक खामी के बजाय सुरक्षा का उद्देश्य है।
Rootless Podman पोर्ट 80 को पब्लिश करने से मना क्यों करता है?
क्योंकि 1024 से नीचे के पोर्ट को बाइंड करने के लिए ऐसे विशेषाधिकार (privilege) की आवश्यकता होती है जो आपके यूजर के पास नहीं है। त्रुटि संदेश में ही समाधान दिया गया है:
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इसके दो समाधान हैं। पूरे होस्ट के लिए थ्रेशोल्ड को कम करें:
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अंतिम कमांड को 80 आउटपुट देना चाहिए। यह स्पष्ट रहे कि वह सेटिंग क्या करती है: अब मशीन का हर यूजर 80 और 443 पोर्ट बाइंड कर सकता है, न कि केवल वह यूजर जो कंटेनर चला रहा है। एक सिंगल-एडमिन VPS पर यह एक स्वीकार्य समझौता है। ऐसी मशीन पर जहाँ अन्य लोगों के अकाउंट्स भी हों, यह सुरक्षित नहीं है। दूसरा समाधान यह है कि पोर्ट 8080 पर पब्लिश करें और सामने एक reverse proxy लगाएँ, जहाँ आप certbot on nginx द्वारा जारी और नवीनीकृत किए गए सर्टिफिकेट रखना चाहेंगे।
Rootless पब्लिशिंग इस बात को भी बदल देती है कि आपका एप्लिकेशन क्या देखता है। Podman 4.x डिफ़ॉल्ट रूप से rootlesskit पोर्ट हैंडलर के साथ slirp4netns का उपयोग करता है, और फॉरवर्ड किए गए कनेक्शन एक रीराइट किए गए सोर्स एड्रेस के साथ आते हैं, इसलिए एक्सेस लॉग में हर विजिटर 10.0.2.100 के रूप में दर्ज होता है। Podman 5.0 ने डिफ़ॉल्ट को pasta में बदल दिया है, जो वास्तविक क्लाइंट एड्रेस को बनाए रखता है। 4.x पर, --network slirp4netns:port_handler=slirp4netns थ्रूपुट में कुछ कमी की कीमत पर वास्तविक सोर्स एड्रेस को रिस्टोर कर देता है।
यहाँ एक अच्छी बात यह है। Rootless पब्लिश किया गया पोर्ट एक सामान्य लिसनिंग सॉकेट है जो एक सामान्य प्रोसेस के स्वामित्व में होता है, इसलिए आपके फायरवॉल के इनपुट नियम इस पर लागू होते हैं। Docker पोर्ट्स को NAT (network address translation) नियमों और अपने स्वयं के फॉरवर्डिंग एक्सेप्ट्स को लिखकर पब्लिश करता है, और यही कारण है कि पब्लिश किया गया Docker पोर्ट उस ufw नियम को अनदेखा कर देता है जिसे आप ब्लॉक समझ रहे थे। Rootful Podman भी इसी तरह की प्लंबिंग का उपयोग करता है और उसी जाल में फंस जाता है। 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 की सूची दिखानी चाहिए, क्योंकि वे केवल एक ही set हैं। Name resolution भी काम करता है: Podman का default network backend, netavark, aardvark-dns चलाता है, इसलिए user-defined network पर मौजूद containers एक-दूसरे को नाम से ढूँढ लेते हैं।
सीमाएँ वास्तविक हैं। जो कुछ भी /var/run/docker.sock को mount करता है, उसे Podman socket की ओर point करना होगा या हटाना होगा। 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 होता है जो ऐसी फाइल को systemd service के रूप में चलाता है। यह सेवाओं को समूहबद्ध करने का वास्तव में एक अलग तरीका है, और यदि आपके भविष्य में कहीं भी Kubernetes है, तो Podman चुनने का यह सबसे मजबूत कारण है।
Daemon के बिना Auto-start: Quadlet units
Quadlet एक systemd generator है। यह बूट के समय container का वर्णन करने वाली एक छोटी फ़ाइल को वास्तविक systemd service में बदल देता है। फ़ाइलें rootless user के लिए ~/.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 लगभग खाली हो सकता है, क्योंकि section header ही volume बनाता है:
[Volume]systemctl --user daemon-reload
systemctl --user start caddy
systemctl --user status caddy
journalctl --user -u caddy -n 50Service का नाम फ़ाइल के नाम से आता है: caddy.container बदलकर caddy.service हो जाता है। systemctl --user enable caddy न चलाएं। उत्पन्न units को enable नहीं किया जा सकता है, और systemd Failed to enable unit: Unit /run/user/1000/systemd/generator/caddy.service is transient or generated. का उत्तर देता है। [Install] section ही वह है जो बूट के समय container को शुरू करता है, और daemon-reload वह है जो फ़ाइल को edit करने के बाद unit को फिर से generate करता है।
अब वह सेटिंग जो लगभग सभी को परेशान करती है:
sudo loginctl enable-linger deploy
loginctl show-user deploy --property=LingerLinger=yes की अपेक्षा करें। Linger के बिना, जब आपका अंतिम SSH connection बंद होता है तो systemd पूरे user session को समाप्त कर देता है, इसलिए हर rootless container उसके साथ रुक जाता है और बूट पर उनमें से कोई भी वापस नहीं आता है। जो containers log out करने पर गायब हो जाते हैं, वे हमेशा इसी कारण से होते हैं।
चूंकि container एक सामान्य service unit की मुख्य प्रक्रिया है, इसलिए systemd के अपने controls सीधे लागू होते हैं। [Service] section में MemoryMax= और CPUQuota= बिल्कुल वैसे ही व्यवहार करते हैं जैसे वे systemd के साथ सीमित किसी अन्य service के लिए करते हैं। इसके लिए cgroup v2 (control group version 2) की आवश्यकता होती है, जिसका उपयोग Ubuntu 22.04 के बाद से डिफ़ॉल्ट रूप से कर रहा है। podman info | grep -i cgroup के साथ पुष्टि करें।
Updates के लिए एक matching mechanism है। AutoUpdate=registry और systemctl --user enable --now podman-auto-update.timer एक ही tag पर नए image के लिए registry की जाँच करते हैं, unit को restart करते हैं, और यदि नया container शुरू होने में विफल रहता है तो पिछले image पर वापस (roll back) चले जाते हैं। यह देखने के लिए कि क्या बदलेगा, पहले podman auto-update --dry-run चलाएं। पुराना podman generate systemd command अभी भी मौजूद है और deprecated है, इसलिए किसी भी नई चीज़ के लिए 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 उन कमांड्स को कवर करता है जिन्हें आप दिन भर टाइप करते हैं: run, ps, logs, exec, build, pull, push, inspect, cp, volume, network।
जो चीजें स्थानांतरित नहीं होती हैं, उनकी सूची छोटी और अधिक सटीक है। Swarm mode का कोई समकक्ष नहीं है, इसलिए Swarm stack के लिए कोई स्थान नहीं है। जो टूल्स Docker socket से बात करते हैं, उन्हें Podman socket को export करने की आवश्यकता होती है, और कुछ अभी भी अंतर को पहचान लेते हैं; Traefik का Docker provider तब काम करता है जब उसे /run/user/<uid>/podman/podman.sock पर पॉइंट किया जाता है, जबकि Watchtower के लिए कोई जगह नहीं है, क्योंकि podman auto-update वह काम करता है। स्टोरेज अलग है, इसलिए Podman उन इमेजेस को नहीं देख सकता जिन्हें आपने पहले ही Docker के साथ pull किया है, और एक व्यस्त Docker host पर podman images खाली शुरू होता है।
चल रहे stack को migrate करना, चरण-दर-चरण
- उस unprivileged user को बनाएँ या चुनें जो containers का स्वामी होगा, और पुष्टि करें कि उसके पास
/etc/subuidमें एक range है। - registry से आए किसी भी image को fully qualified names का उपयोग करके फिर से pull करें। Podman का अपना image store होता है और यह Docker के store को नहीं पढ़ेगा।
- स्थानीय रूप से बनी images को
docker save app:1.4 | podman loadका उपयोग करके स्थानांतरित करें। - Docker container को रोकें, प्रत्येक volume की सामग्री को
/var/lib/docker/volumes/<name>/_dataसे बाहर copy करें, और फिरpodman unshare chown -R 1000:1000 <path>के साथ ownership को ठीक करें। - port के प्रश्न को हल करें: reverse proxy के पीछे 1024 से ऊपर port 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 को स्थानांतरित करें, एक दिन तक उसकी निगरानी करें, फिर अगली service को स्थानांतरित करें।
Podman बनाम Docker: आपके VPS पर कौन सा बेहतर है?
यदि आपका stack उन compose files में है जिन्हें अन्य लोग भी maintain करते हैं, या यदि आप ऐसे tooling पर निर्भर हैं जो Docker socket से बात करता है, तो Docker का ही उपयोग करें। दूसरों द्वारा लिखे गए code के साथ compatibility एक वास्तविक विशेषता है, और Docker में यह अधिक है। जिस टीम के laptops पर Docker चलता है, उन्हें production में भी वही engine चलाने से ठोस लाभ मिलता है।
यदि आपका VPS कुछ ऐसी services चलाता है जिन्हें आप पूरी तरह से नियंत्रित करते हैं, या यदि आप चाहते हैं कि प्रत्येक application अपने स्वयं के unprivileged user के अंतर्गत चले और box पर कोई docker group न हो, तो Podman पर switch करें। Distribution alignment भी मायने रखती है: RHEL और इसके rebuilds में Podman को supported engine के रूप में ship किया जाता है, इसलिए उन systems पर Podman का उपयोग करने में कम समस्याएं आती हैं। यदि आप पहले से ही systemd units के साथ सब कुछ supervise करते हैं, तो quadlets आपको एक नए tool के बजाय एक छूटे हुए हिस्से के मिलने जैसा महसूस होगा।
एक मध्यम विकल्प का उल्लेख करना उचित है। Rootful Podman काफी हद तक Docker की तरह व्यवहार करता है, wrapper के माध्यम से docker command को बनाए रखता है, और हमेशा चलने वाले daemon को हटा देता है। यह rootless सुविधा को छोड़ देता है, जो कि वह हिस्सा है जो आपकी security स्थिति को बदलता है, इसलिए इसे केवल एक अस्थायी पड़ाव मानें।
यदि आप अभी भी अपना पहला container host बना रहे हैं, तो एक नए VPS पर Docker setup और hardening का रास्ता छोटा है, और वह ज्ञान व्यर्थ नहीं जाएगा। Images और volumes दोनों engines के अंतर्गत समान objects हैं, इसलिए बाद में बदलाव करने पर केवल आपकी services के supervise होने का तरीका बदलेगा, बाकी बहुत कम चीजें बदलेंगी।
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 की ओर point करना होगा, और 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 output देता है या नहीं। 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 व उसके बाद के UIDs को आपकी 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 उस file को पढ़ता है और सीधे 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 पर, उन services पर जो Docker socket को mount करती हैं, और restart: always पर कुछ कठिनाइयाँ आ सकती हैं, जिसे reboot के बाद चालू रखने के लिए quadlet unit और linger की आवश्यकता होती है।
क्या rootless वास्तव में containers को अधिक सुरक्षित बनाता है?
यह एक विशिष्ट जोखिम को हटा देता है: यदि कोई process rootless container से बाहर निकलती है, तो उसके पास root के बजाय आपके unprivileged user की permissions होती हैं। यह सुरक्षा का एक महत्वपूर्ण स्तर है, और यही कारण है कि rootless Podman में root-equivalent docker group का कोई समकक्ष नहीं है। यह kernel vulnerabilities को नहीं रोकता है, और यह उन files की सुरक्षा नहीं करता जिन्हें आपका user पढ़ सकता है, इसलिए बाकी सभी सुरक्षा उपाय वैसे ही रखें जैसे आप किसी भी server पर करते हैं।