حقیقی سرورز کے لیے Docker Compose cheat sheet
روزمرہ کام کے لیے Docker Compose کی ضروری commands ایک جگہ پائیں: lifecycle، تبدیلیاں نافذ کرنا، logs، shells، networks، volumes اور محفوظ cleanup۔
وہ Compose commands جنہیں آپ عملی طور پر استعمال کریں گے
Docker Compose میں چالیس سے زیادہ subcommands شامل ہیں۔ سرور پر روزمرہ کام کے لیے عموماً تقریباً ایک درجن commands کافی ہوتی ہیں۔ یہ صفحہ انہیں آپ کے کام کے مطابق گروپ کرتا ہے، ہر command کی ایک واضح وجہ بیان کرتا ہے، اور جہاں کسی command میں اہم پیچیدگی ہو وہاں تفصیلی وضاحت کی طرف رہنمائی کرتا ہے۔
یہاں ہر جگہ Compose V2 استعمال ہوتا ہے: docker compose، جس میں space شامل ہے، نہ کہ پرانی docker-compose script۔ V2 ایک Go plugin ہے جو Docker Engine کے ساتھ install ہوتا ہے، جبکہ V1 موجودہ packages سے ختم ہو چکا ہے۔ اس لیے July 2026 تک نئے Ubuntu box پر docker-compose: command not found کا ملنا خرابی نہیں بلکہ متوقع صورت ہے۔ docker compose version سے تصدیق کریں۔ اگر اس سے کچھ بھی ظاہر نہ ہو تو docker-compose-plugin package install کریں۔
ذیل کی ہر command اس directory سے چلائیں جس میں آپ کی compose.yaml موجود ہو، کیونکہ Compose project name اسی directory سے لیتا ہے اور file بھی اسی کے لحاظ سے تلاش کرتا ہے۔ یہی command اس سے ایک level اوپر چلانے پر Compose no configuration file provided: not found کے ساتھ رک جاتا ہے۔ اگر file format آپ کے لیے نیا ہے تو VPS پر پہلی Compose file سے شروع کریں، پھر commands کے لیے یہاں واپس آئیں۔
لائف سائیکل: وہ چار commands جو آپ استعمال کرتے ہیں، اور وہ ایک جو containers ختم کر دیتی ہے
docker compose up -d
docker compose up -d --wait
docker compose stop
docker compose start
docker compose restart web
docker compose downup -d network بناتا ہے، containers بناتا ہے، انہیں start کرتا ہے، اور واپس آ جاتا ہے۔ یہ اسی وقت واپس آ جاتا ہے جب containers صرف create ہو جائیں۔ اسی لیے اس کے فوراً بعد curl probe چلانے والی deploy script پہلی کوشش میں اکثر ناکام ہو جاتی ہے۔ up -d --wait اس وقت تک انتظار کرتا ہے جب تک healthcheck کی وضاحت کرنے والی ہر service healthy نہ بتا دے، اور اگر کوئی service کبھی healthy نہ ہو تو non-zero کے ساتھ exit ہوتا ہے۔ یہ flag اپنے پیچھے موجود check جتنا ہی مؤثر ہوتا ہے، اس لیے automation میں اس پر انحصار کرنے سے پہلے ایسا healthcheck لکھیں جس پر Compose اعتماد کر سکے۔
stop containers کو halt کرتا ہے اور انہیں برقرار رکھتا ہے، اس لیے start انہی containers کو اسی writable layer کے ساتھ دوبارہ چلاتا ہے۔ down containers کو stop کرنے کے بعد انہیں اور project network کو remove کر دیتا ہے۔ container کے اندر اور volume سے باہر لکھی گئی ہر چیز بھی ان کے ساتھ ختم ہو جاتی ہے۔ Compose میں یہ سب سے مہنگی غلط فہمی ہے، اور down اور stop کے درمیان مکمل فرق اس کی وضاحت کرتا ہے کہ نقصان کہاں ہوتا ہے۔
restart reload نہیں ہے۔ یہ اسی configuration کے ساتھ موجودہ container کو stop اور start کرتا ہے، اس لیے تبدیل شدہ environment variable، نیا image tag یا ترمیم شدہ port mapping کا کوئی اثر نہیں ہوتا۔ file change نافذ کرنے کے لیے آپ دوبارہ up -d چلاتے ہیں۔ Compose ہر service کا موازنہ اس کے running container سے کرتا ہے اور صرف ان containers کو دوبارہ بناتا ہے جن کی configuration تبدیل ہوئی ہو۔
تبدیلی لاگو کرنا: دوبارہ بنانا، pull کرنا، یا rebuild کرنا
docker compose up -d --force-recreate
docker compose pull && docker compose up -d
docker compose build --no-cache web
docker compose up -d --build webup -d اس وقت کچھ نہیں کرتا جب کوئی تبدیلی نہ ہوئی ہو، اسی لیے اسے بار بار چلانا محفوظ ہے۔ --force-recreate اس موازنے کو نظرانداز کرتا ہے اور configuration یکساں ہونے کے باوجود ہر container کو replace کر دیتا ہے، اس لیے container کے اندر موجود غیر معمولی state صاف کرنے کا یہ تیز ترین طریقہ ہے۔
image کو update کرنے کے لیے دو commands درکار ہوتی ہیں، کیونکہ یہ دونوں مختلف کام کرتی ہیں۔ pull file میں نامزد ہر tag کی موجودہ image download کرتا ہے۔ اس کے بعد up -d دیکھتا ہے کہ service کی image ID اس کے running container سے مطابقت نہیں رکھتی، اور اسے دوبارہ بناتا ہے۔ pull کو چھوڑ دیں تو up -d پچھلے مہینے کی latest کو بغیر کسی error کے running رکھتا ہے۔ اس کے برعکس multi-service stack میں خطرہ یہ ہوتا ہے کہ تمام services کے لیے بیک وقت latest pull کرنے سے وہ app بھی خراب ہو سکتی ہے جو صرف دس seconds پہلے درست کام کر رہی تھی۔ اسی لیے self-hosted AFFiNE workspace اپنی چاروں image tags کو الگ الگ pin کرتا ہے۔
build ان services پر لاگو ہوتا ہے جو image: کے بجائے build: section define کرتی ہیں۔ up -d --build ایک ہی step میں build اور start کرتا ہے، اور code تبدیل کرتے وقت یہی معمول کا طریقہ ہے۔ --no-cache صرف اس وقت استعمال کریں جب cached layer واضح طور پر پرانی ہو، کیونکہ یہ ہر layer کو شروع سے rebuild کرتا ہے۔
جو کچھ چل رہا ہے اسے دیکھنا
docker compose ps
docker compose ps -a
docker compose logs -f --tail=100
docker compose logs --since 15m --timestamps db
docker compose top
docker compose lsps صرف چلنے والے containers کی فہرست دکھاتا ہے۔ start کے دوران crash ہونے والی service وہاں اس وقت تک نظر نہیں آتی جب تک آپ -a شامل نہ کریں۔ اس لیے ps میں غائب container کا ps -a میں Exited (1) کے طور پر دکھائی دینا startup failure کی معمول کی صورت ہے۔ پہلے exit code پڑھیں، پھر logs پڑھیں۔
logs -f بیک وقت ہر service کی پیروی کرتا ہے اور ہر سطر کے آغاز میں service کا نام لکھتا ہے۔ جب services ایک دوسرے سے بات کرتی ہوں اور events کی ترتیب اہم ہو، تو یہی view درکار ہوتا ہے۔ دائرہ محدود کرنے کے لیے service کا نام دیں۔ ایک ماہ سے چلنے والے container میں --tail=100 اہم ہے، کیونکہ default پوری history دکھاتا ہے اور terminal بھر دیتا ہے۔ --since 15m اس سوال کا جواب دیتا ہے جو عموماً آپ کے سامنے ہوتا ہے: ابھی کیے گئے restart کے دوران کیا ہوا۔
top ہر container کے اندر موجود processes کی فہرست دکھاتا ہے۔ اس سے یہ فرق واضح ہوتا ہے کہ "container چل رہا ہے" اور "اس کے اندر process چل رہا ہے"۔ ls موجودہ directory سے باہر جا کر host پر موجود ہر Compose project کو اس کی status کے ساتھ دکھاتا ہے۔ اس طرح آپ وہ stack تلاش کر سکتے ہیں جسے آپ نے تین ماہ پہلے start کیا تھا۔
سروس کے اندر shell حاصل کرنا
docker compose exec web sh
docker compose exec -u root web sh
docker compose run --rm web env
docker compose run --rm --no-deps web shexec پہلے سے چل رہے container کے اندر command چلاتا ہے۔ run اسی service definition سے نیا container شروع کرتا ہے۔ جب service اتنی دیر تک نہ چل پائے کہ اس میں exec کیا جا سکے، تو یہی درکار ہوتا ہے۔ run کو ہمیشہ --rm کے ساتھ استعمال کریں، کیونکہ اس کے بغیر ہر invocation ایک stopped container چھوڑ دیتی ہے۔ یہ containers جمع ہوتے رہتے ہیں، یہاں تک کہ docker compose ps -a ناقابلِ مطالعہ ہو جاتا ہے۔
bash سے پہلے sh آزمائیں۔ Alpine پر مبنی images میں bash موجود نہیں ہوتا، اور failure message exec: "bash": executable file not found in $PATH ہوتا ہے۔ run میں --no-deps شامل کرنے سے service کی dependencies نظرانداز ہو جاتی ہیں۔ اس طرح فوری configuration check کے دوران پورا database شروع نہیں ہوتا۔
run --rm web env یہ دیکھنے کا تیز ترین طریقہ ہے کہ service کو حقیقت میں کون سا environment ملا، جب ہر .env file، environment: block اور shell variable کو merge کیا جا چکا ہو۔ جب کوئی value غلط ہو تو عموماً وجہ merge order ہوتی ہے، اور Compose env files اور secrets کو resolve کیسے کرتا ہے میں بتایا گیا ہے کہ کون سا source ترجیح پاتا ہے۔
نیٹ ورکس، ports اور name resolution
docker compose port web 80
docker compose exec web getent hosts db
docker compose config --networksCompose ہر service کو ایک ہی project network پر رکھتا ہے، اور ہر service name اس network پر DNS name ہوتا ہے۔ جب resolution کام کر رہی ہو تو getent hosts db کو web کے اندر چلانے سے container IP ظاہر ہوتا ہے، اور جب resolution ناکام ہو تو کچھ بھی ظاہر نہیں ہوتا۔ اس طرح دو سیکنڈ میں معلوم ہو جاتا ہے کہ "کیا یہ containers ایک دوسرے سے رابطہ کر سکتے ہیں؟" اگر name resolve ہو جائے لیکن connection refused ہو، تو db کے اندر process 127.0.0.1 کے بجائے 0.0.0.0 پر bound ہے۔ اسی لیے وہ دوسرے container سے آنے والا کوئی packet قبول نہیں کرتا۔ اس model کی مزید وضاحت Compose networks اور service DNS کیسے کام کرتے ہیں میں ہے۔
port web 80 اس host address اور port کو ظاہر کرتا ہے جس پر container کا port publish کیا گیا ہے۔ جب mapping کسی variable سے آئی ہو تو اس سے اندازہ لگانے کی ضرورت نہیں رہتی۔ Port publish کرنے سے Docker کے زیرِ انتظام firewall rule بھی بن جاتا ہے۔ یہ rule آپ کے rules سے پہلے لاگو ہوتا ہے۔ اس لیے جو service آپ نے private سمجھی تھی، وہ internet کے لیے کھلی ہو سکتی ہے۔ اس صورتِ حال کی وضاحت published Docker ports، ufw کو bypass کیوں کرتے ہیں میں ہے۔ ان ports کو unpublished چھوڑنا اور services کے سامنے project network پر ایک authentication proxy رکھنا زیادہ محفوظ طریقہ ہے۔ یہی سہولت Authentik کو single sign-on layer کے طور پر چلانا فراہم کرتی ہے۔
Volumes اور data
docker compose config --volumes
docker compose cp db:/etc/postgresql/pg_hba.conf ./pg_hba.conf
docker compose down -vconfig --volumes پروجیکٹ میں اعلان کردہ named volumes کو ہر سطر میں ایک volume کے طور پر دکھاتا ہے۔ یہی وہ فہرست ہے جس کا backup لینا ضروری ہے۔ جب volumes میں ناقابلِ تلافی data موجود ہو تو backup کی درست command بھی فہرست جتنی ہی اہم ہوتی ہے۔ اسی لیے PhotoPrism اور Immich کا موازنہ ہر photo server کے لیے درکار dump اور copy commands واضح کرتا ہے۔ cp shell کھولے بغیر container کے اندر یا باہر file copy کرتا ہے۔ اس میں service:path form اس جانب استعمال ہوتا ہے جہاں container موجود ہو۔
down -v containers کے ساتھ ان named volumes کو بھی remove کرتا ہے۔ test stack ختم کرنے کے لیے یہ درست command ہے، لیکن ایسے کسی بھی stack کے لیے غلط ہے جس میں اہم data موجود ہو، کیونکہ اس میں confirmation نہیں ہوتی اور undo کا کوئی طریقہ نہیں ہوتا۔ Bind mounts اس عمل کے بعد بھی برقرار رہتے ہیں، کیونکہ وہ host filesystem میں موجود ہوتے ہیں۔ blast radius میں یہی فرق bind mounts اور named volumes کے درمیان سوچ سمجھ کر انتخاب کرنے کی ایک وجہ ہے۔
ایسا cleanup جو ڈیٹا ضائع کیے بغیر disk خالی کرے
docker compose down --remove-orphans
docker system df
docker image prune -a
docker builder prune--remove-orphans ایسے containers حذف کرتا ہے جو project سے متعلق ہوں لیکن file میں موجود نہ ہوں۔ service کا نام تبدیل کرنے کے بعد یہی صورت حال پیدا ہوتی ہے۔ اس کے بغیر وہ containers چلتے رہتے ہیں اور docker compose ps کو دکھائی نہیں دیتے۔
docker system df کسی چیز کو حذف کرنے سے پہلے دکھاتا ہے کہ disk space کہاں استعمال ہو رہی ہے۔ یہ images، containers، local volumes اور build cache کو الگ الگ دکھاتا ہے اور ہر ایک کے لیے reclaimable مقدار بھی بتاتا ہے۔ image prune -a ایسی ہر image حذف کرتا ہے جس کی طرف کوئی tag اشارہ نہیں کرتا۔ جس server پر کسی بڑی image کے کئی versions pull کیے گئے ہوں، وہاں عموماً اسی سے سب سے زیادہ space خالی ہوتی ہے۔ builder prune build cache صاف کرتا ہے، جو ہر ایسے server پر خاموشی سے بڑھتا رہتا ہے جہاں اپنی images build کی جاتی ہوں۔
ان میں سے کوئی بھی named volume کو متاثر نہیں کرتا۔ صرف docker volume prune اور docker compose down -v ایسا کرتے ہیں۔
کسی خرابی سے پہلے فائل کی جانچ
docker compose config --quiet
docker compose config --services
docker compose --dry-run up -dconfig --quiet تصدیق کرتا ہے اور کامیابی کی صورت میں کچھ پرنٹ نہیں کرتا، اس لیے اسے deployment سے پہلے کے مرحلے یا git hook میں شامل کیا جاتا ہے۔ سادہ config مکمل طور پر merged اور interpolated فائل پرنٹ کرتا ہے۔ اسی سے تصدیق ہوتی ہے کہ کوئی variable resolve ہوا ہے اور override فائلیں توقع کے مطابق layer ہوئی ہیں۔ Unset variable وہاں خالی value کے طور پر ظاہر ہوتا ہے، اور اس کے ساتھ warning The "X" variable is not set. Defaulting to a blank string. ہوتی ہے۔
--dry-run subcommand flag کے بجائے global flag ہے، اس لیے یہ up سے پہلے آتا ہے۔ یہ Compose کی جانے والی ہر کارروائی پرنٹ کرتا ہے اور کوئی تبدیلی نہیں کرتا۔ اہم stack پر down سے پہلے صرف تیس سیکنڈ صرف کرنا مفید ہے۔
فائلوں، profiles اور projects کے درمیان کام کرنا
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose --profile debug up -d
docker compose -p staging up -dمتعدد -f flags ترتیب کے مطابق merge ہوتے ہیں، اور بعد والی files پہلے والی files کو key کے لحاظ سے override کرتی ہیں۔ ایک چھوٹی production override کے ساتھ ایک base file رکھنے کا یہ معیاری طریقہ ہے، لیکن lists اور maps کے لیے rules مختلف ہوتے ہیں۔ کسی غیر متوقع نتیجے کی debugging سے پہلے Compose متعدد files کو کیسے merge کرتا ہے پڑھیں۔
--profile اس profile کے ساتھ tagged services کو untagged services کے ساتھ start کرتا ہے۔ اس طرح debug tooling عام up سے الگ رہتی ہے۔ -p project name مقرر کرتا ہے، اس لیے ایک ہی stack کی دو copies الگ networks اور الگ volume names کے ساتھ ساتھ چل سکتی ہیں۔ reboot کے بعد stack بحال کرنا ایسا command نہیں جسے آپ خود type کریں۔ اس کے لیے ایک unit ہوتی ہے جو یہ کام خود چلاتی ہے، جیسا کہ boot پر Compose stacks شروع کرنا میں بیان کیا گیا ہے۔
FAQ
docker-compose کو hyphen سے کس چیز نے replace کیا؟
Compose V2، جسے docker compose میں space کے ساتھ چلایا جاتا ہے۔ یہ Docker Engine کے ساتھ bundled plugin ہے، اور V1 کا Python tool موجودہ packages کے ذریعے مزید install نہیں ہوتا۔ اگر space والی شکل کوئی output نہ دے تو اپنی distribution کے لیے docker-compose-plugin package install کریں۔ پرانے scripts کو alias شامل کرنے کے بجائے space والی شکل میں update کریں، کیونکہ V2 میں ایسے flags موجود ہیں جو V1 میں نہیں تھے۔
docker compose restart میری configuration change کیوں نہیں اٹھاتا؟
restart موجودہ container کو اسی configuration کے ساتھ stop اور start کرتا ہے جس کے ساتھ وہ بنایا گیا تھا، اور یہ compose.yaml کو دوبارہ نہیں پڑھتا۔ Environment variables، ports، volumes یا image tag میں کسی بھی change کے لیے docker compose up -d درکار ہے۔ یہ ہر service کا چلتے ہوئے container سے موازنہ کرتا ہے اور مختلف ہونے والی services کو دوبارہ بناتا ہے۔ جب file میں کوئی change نہ ہو تب بھی replacement کرانا ہو تو --force-recreate شامل کریں۔
میں کسی service کو نئی image پر کیسے update کروں؟
پہلے docker compose pull چلائیں، پھر docker compose up -d۔ Pull file میں موجود ہر tag کی موجودہ image حاصل کرتا ہے، اور up -d ایسی service کو دوبارہ بناتا ہے جس کی image ID اس کے container سے مطابقت نہ رکھتی ہو۔ اکیلے up -d چلانے سے disk پر پہلے سے موجود image دوبارہ استعمال ہوتی ہے۔ اسی وجہ سے latest پر pinned stack کئی ماہ پرانی build پر چلتی رہ سکتی ہے، بغیر کسی error کے۔
Live server پر کون سے cleanup commands محفوظ ہیں؟
docker system df، docker image prune -a اور docker builder prune صرف images اور cache remove کرتے ہیں۔ اس لیے چلتی ہوئی services کام کرتی رہتی ہیں اور named volumes متاثر نہیں ہوتے۔ خطرناک جوڑی docker compose down -v اور docker volume prune ہے، جو named volumes کو کسی prompt کے بغیر delete کر دیتی ہے۔ پہلے docker compose config --volumes چلائیں تاکہ معلوم ہو کہ کیا خطرے میں ہے۔
کیا میں پوری stack start کیے بغیر ایک command چلا سکتا ہوں؟
ہاں۔ docker compose run --rm --no-deps web sh، web service definition سے ایک single container start کرتا ہے، اس کی dependencies کو skip کرتا ہے، اور exit کرنے پر container remove کر دیتا ہے۔ جب container پہلے ہی چل رہا ہو تو اس کے بجائے exec استعمال کریں، کیونکہ exec چلتے ہوئے process سے attach ہوتا ہے اور آپ کو service کی حقیقی موجودہ state دکھاتا ہے۔