Skip to content
VDS · Docker اور کنٹینرز

Docker نیٹ ورکس اور پورٹ فارورڈنگ

کنٹینرز ایک دوسرے کو کیسے دیکھتے ہیں، پورٹ شائع کرنا سادہ EXPOSE سے کیسے مختلف ہے، اور Docker ufw کے قواعد کو کیوں بائی پاس کرتا ہے۔

اپ ڈیٹ 23 اگست، 2026

کنٹینر کے مسائل میں سے آدھے نیٹ ورک سے متعلق ہوتے ہیں: کوئی سروس ڈیٹا بیس تک نہیں پہنچ پاتی، کوئی پورٹ پہلے سے قبضے میں ہوتی ہے، یا پینل اچانک پورے انٹرنیٹ پر کھل جاتا ہے۔ آئیے سمجھتے ہیں کہ یہ سب کیسے کام کرتا ہے۔

تین قسم کے نیٹ ورک

  • bridge — ڈیفالٹ۔ کنٹینرز کو اندرونی ایڈریس ملتے ہیں اور وہ آپس میں بات چیت کرتے ہیں؛ باہر جانا ہوسٹ کے NAT کے ذریعے ہوتا ہے۔
  • host — کنٹینر براہ راست ہوسٹ کا نیٹ ورک استعمال کرتا ہے؛ پورٹ پبلش کرنا نہ ضروری ہے نہ کام کرتا ہے۔ تیز، مگر کوئی آئسولیشن نہیں: کنٹینر کی پورٹ 80 ہوسٹ کی پورٹ 80 ہی ہے۔
  • none — کوئی نیٹ ورک ہی نہیں۔ ایسے کاموں کے لیے جنہیں نیٹ ورک کی ضرورت نہ ہو۔

آپ کا بنایا ہوا یا Compose کا بنایا ہوا کسٹم نیٹ ورک ڈیفالٹ bridge سے ایک اہم بات میں مختلف ہوتا ہے: اس میں نام سے پہچان کام کرتی ہے۔ app کنٹینر db نام سے db کنٹینر تک پہنچ سکتا ہے۔

docker network create backend
docker network ls
docker network inspect backend

Compose میں ایسا نیٹ ورک ہر پروجیکٹ کے لیے خودکار طور پر بن جاتا ہے۔

پورٹ پبلش کرنا

ports:
  - "127.0.0.1:8080:8080"   # accessible only from the machine itself
  - "80:80"                 # accessible to the whole internet

بائیں طرف ہوسٹ کی پورٹ ہے، دائیں طرف کنٹینر کے اندر کی پورٹ۔ امیج میں EXPOSE ہدایت کچھ پبلش نہیں کرتی: یہ صرف ایک نوٹ ہے کہ ایپلیکیشن کس پورٹ پر سنتی ہے۔

اصول سادہ ہے: صرف وہی پبلش کریں جو باہر سے قابل رسائی ہونا ضروری ہو۔ ڈیٹا بیس، پینل اور اندرونی API کو 127.0.0.1 پر رکھیں، اور سرٹیفکیٹ والا ویب سرور انہیں باہر کے لیے کھولے۔

Docker خود iptables کے قواعد لکھتا ہے اور یہ کام ufw کے سنبھالے ہوئے chains سے پہلے کرتا ہے۔ -p 8080:8080 کے طور پر پبلش کی گئی پورٹ انٹرنیٹ سے قابل رسائی ہوگی، چاہے ufw "deny" دکھائے۔ فائر وال پر بھروسا نہ کریں — پورٹ کو 127.0.0.1 سے بائنڈ کریں۔

کنٹینرز کے درمیان رابطہ

services:
  app:
    networks: [frontend, backend]
  db:
    networks: [backend]
  proxy:
    networks: [frontend]
    ports:
      - "80:80"
      - "443:443"

networks:
  frontend:
  backend:

یہاں ڈیٹا بیس صرف ایپلیکیشن کے لیے قابل رسائی ہے، اور باہر کی طرف صرف ویب سرور کھلا ہے۔ یہ کسی بھی اسٹیک کے لیے درست سیٹ اپ ہے۔

کنٹینر کے اندر پڑوسی کو اس کے سروس نام سے مخاطب کریں: postgres://db:5432/app۔ کنٹینر کے اندر localhost کا مطلب خود کنٹینر ہوتا ہے، ہوسٹ نہیں — یہ latest کے بعد دوسری سب سے عام غلطی ہے۔

ہوسٹ پر خود چلنے والی سروس تک کنٹینر سے پہنچنے کے لیے host.docker.internal نام استعمال کریں اور یہ شامل کریں:

extra_hosts:
  - "host.docker.internal:host-gateway"

تشخیص

docker compose exec app ping -c2 db
docker compose exec app getent hosts db
sudo ss -tulpn | grep LISTEN
docker port <container>

ss دکھائے گا کہ پورٹ واقعی کس انٹرفیس پر سن رہی ہے: 0.0.0.0:8080 — باہر کے لیے کھلی، 127.0.0.1:8080 — نہیں۔

عام غلطیاں

  • "پورٹ پہلے سے استعمال میں ہے"۔ اس پر کوئی دوسرا کنٹینر یا ہوسٹ سروس قابض ہے۔ sudo ss -tulpn | grep :80 مجرم ڈھونڈ لے گا۔
  • مختلف Compose پروجیکٹس کے کنٹینرز ایک دوسرے کو نہیں دیکھ سکتے۔ ہر پروجیکٹ کا اپنا نیٹ ورک ہوتا ہے۔ انہیں واضح طور پر networks: { shared: { external: true } } کے ذریعے جوڑیں۔
  • ایپلیکیشن کنٹینر کے اندر 127.0.0.1 پر سن رہی ہے۔ پھر پبلش کرنے سے فائدہ نہیں: آپ کنٹینر کے باہر سے اس تک نہیں پہنچ سکتے۔ ایپلیکیشن کو 0.0.0.0 پر سننے کے لیے کنفیگر کریں۔
  • بینڈوڈتھ۔ فی ہوسٹ مشترکہ طور پر 500 Mbps تک۔ فائل ڈسٹری بیوشن اسے باقی سب کے ساتھ بانٹتی ہے۔