Portlar — -p, konteynerga brauzerdan kirish
Muammodan boshlaylik
docker run -d --name api node-api
Konteyner ishlayapti, loglarda "Server 3000-portda ishga tushdi". Brauzerda http://localhost:3000 — "Ulanib bo'lmadi". Ilova ishlayapti, lekin unga yetib bo'lmaydi.
Yoki teskari muammo: ikki loyihada ham PostgreSQL 5432-portda — ikkinchisi ishga tushmaydi: "port is already allocated".
Port qanday ishlaydi
Konteynerning o'z tarmog'i bor (3-dars). Uning portlari — ichki. Tashqaridan kirish uchun port ulash (port mapping, publishing) kerak:
Brauzer → localhost:8080 ─────→ [ Docker ] ─────→ konteyner:80 → Nginx
(host porti) (konteyner porti)
docker run -d -p 8080:80 nginx
# ↑ ↑
# HOST KONTEYNER
Tartib: host:konteyner — chap tomon — sizning kompyuteringiz, o'ng tomon — konteyner ichi. Eng ko'p adashtiriladigan joy.
Variantlar
-p 8080:80 # host 8080 → konteyner 80
-p 80:80 # bir xil port
-p 3000:3000
-p 127.0.0.1:5432:5432 # FAQAT shu kompyuterdan kirish mumkin
-p 5432 # host porti tasodifiy tanlanadi
-p 8080:80 -p 8443:443 # bir nechta port
-p 5000-5010:5000-5010 # diapazon
-p 53:53/udp # UDP
Tasodifiy port qaysi biri ekanini bilish:
docker port mening-konteyner
# 5432/tcp -> 0.0.0.0:55012
Bir xil xizmat — turli portlarda
Ikki loyiha, ikkala ham PostgreSQL:
docker run -d --name pg-dokon -e POSTGRES_PASSWORD=x -p 5432:5432 postgres:17
docker run -d --name pg-blog -e POSTGRES_PASSWORD=x -p 5433:5432 postgres:17
docker run -d --name pg-eski -e POSTGRES_PASSWORD=x -p 5434:5432 postgres:13
Konteyner ichida uchalasi ham 5432 da ishlaydi. Tashqarida — 5432, 5433, 5434. Hatto turli versiyalar — bir vaqtda, to'qnashuvsiz. Kompyuterga o'rnatilgan bazalar bilan bu deyarli imkonsiz.
Ulanish: localhost:5433 → blog bazasi.
Xavfsizlik: 0.0.0.0 va 127.0.0.1
-p 5432:5432
Standart holatda port barcha tarmoq interfeyslarida ochiladi (0.0.0.0) — ya'ni nafaqat kompyuteringizdan, balki tarmoqdagi boshqa qurilmalardan ham. Kafe Wi-Fi sida — boshqa mijozlar sizning bazangizga ulanishga urinishi mumkin. Serverda — butun internet.
-p 127.0.0.1:5432:5432
Faqat lokal kirish. Baza, Redis, admin panellar uchun — doim shunday.
[!WARNING] Linux serverda Docker o'z port qoidalarini
iptablesga to'g'ridan-to'g'ri yozadi va UFW firewall ni chetlab o'tadi.ufw deny 5432yozdingiz, lekin-p 5432:5432bilan ishlayotgan konteyner baribir internetga ochiq. Bu ko'p uchraydigan va xavfli xato — minglab MongoDB va Redis bazalari aynan shu sababli o'g'irlangan. Serverda: bazalarni-psiz (faqat Docker tarmog'i ichida, 24-dars) yoki127.0.0.1:bilan.
Ichki va tashqi portlar
Har bir xizmatni tashqariga ochish shart emas:
Internet → [80/443] Nginx ─→ [3000] API ─→ [5432] PostgreSQL
ochiq ichki ichki
Faqat Nginx ga -p 80:80 -p 443:443. API va baza — tashqi portsiz; ular bir-biri bilan Docker tarmog'i orqali gaplashadi (24-dars). Har bir ochiq port — potentsial hujum nuqtasi.
EXPOSE
Dockerfile larda (va docker ps da) uchraydi:
EXPOSE 3000
Bu — faqat hujjat: "bu image 3000-portni tinglaydi". Hech narsani ochmaydi. Ochish — faqat -p bilan. (docker run -P — barcha EXPOSE qilingan portlarni tasodifiy host portlariga ulaydi.)
Tez-tez uchraydigan muammolar
port is already allocated — host porti band: boshqa konteyner yoki kompyuterdagi dastur (o'rnatilgan MySQL). Boshqa host porti tanlang yoki bandini toping:
docker ps --filter "publish=5432"
Ilova konteynerda ishlayapti, lekin ulanib bo'lmayapti — ilova localhost / 127.0.0.1 ni tinglayapti. Konteyner ichidagi localhost — faqat konteynerning o'zi! Ilova 0.0.0.0 ni tinglashi kerak:
app.listen(3000, '0.0.0.0'); // ✅ Express
// Vite: vite --host 0.0.0.0
// Next.js: next dev -H 0.0.0.0
// Django: python manage.py runserver 0.0.0.0:8000
Bu — boshidagi muammoning eng ko'p uchraydigan sababi.
Nima uchun shunday?
Nima uchun konteyner ichidagi localhost tashqaridan ko'rinmaydi?
Har bir konteynerning o'z tarmoq nomlar maydoni (network namespace) bor — o'z tarmoq interfeyslari, o'z localhost i. Ilova 127.0.0.1 ni tinglasa — u faqat konteyner ichidagi so'rovlarni qabul qiladi. Docker esa tashqaridan kelgan so'rovni konteynerning tashqi interfeysiga yo'naltiradi — 127.0.0.1 ga emas. 0.0.0.0 — "barcha interfeyslar" — ilova har qanday yo'ldan kelgan so'rovni qabul qiladi. Izolyatsiya — xavfsizlik uchun; 0.0.0.0 — ataylab ochish.
Xulosa
Eslab qoling:
-p HOST:KONTEYNER— chap — kompyuter, o'ng — konteyner- Turli host portlari — bir xil xizmatning ko'p nusxasi
127.0.0.1:host:konteyner— faqat lokal; bazalar uchun doim- Linux serverda Docker UFW ni chetlab o'tadi — bazalarni ochmang
- Faqat kerakli xizmatni tashqariga oching (Nginx); qolganlari — ichki tarmoqda
EXPOSE— faqat hujjat- Ilova
0.0.0.0ni tinglasin,localhostni emas
Keyingi dars
10-dars: Muhit o'zgaruvchilari — -e, --env-file