SSD Nodes Learn Hosting plans →
Mga Gabay Matt ConnorNi Matt Connor · Na-update 2026-08-07

Docker Compose networking: default network at DNS

Alamin kung paano gumagana ang default project bridge at DNS gamit ang service name, kailan sulit ang host mode, at bakit nalalampasan ng published port ang UFW.

Ang binubuo ng Compose bago magsimula ang app mo

Nagsisimula ang Docker Compose networking sa isang rule: ang docker compose up ang gumagawa ng private network para sa project, nag-a-attach ng bawat service dito, at nagbibigay-daan sa mga service na maabot ang isa’t isa gamit ang service name. Hindi mo kailangang magsulat ng kahit isang networks: line para makuha iyon. Karamihan ng kalituhan sa Compose networking ay dahil hindi alam na naka-set up na agad ang default na ito.

Narito ang isang maliit na file. I-save ito bilang compose.yaml sa directory na tinatawag na shop.

services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example

I-start ito at tingnan kung ano ang ginawa ng Docker:

docker compose up -d
docker network ls

May network na ngayong tinatawag na shop_default sa listahan. Pinapangalanan ito ng Compose bilang <project>_default, at ang default na project name ay ang lowercase na pangalan ng directory. I-override ito gamit ang docker compose -p myproject up -d o gamit ang top-level na name: myproject sa file. Ang driver nito ay bridge, isang virtual switch sa loob ng host. Bawat container ay binibigyan ng address sa isang private subnet, at ang outbound traffic ay tina-translate sa address ng host habang lumalabas.

Ang docker compose down ang muling nagde-delete sa network na iyon. Kaya maaaring panatilihing bukas ng stale container mula sa lumang project ang isang network: magre-refuse ang Docker gamit ang error while removing network: network shop_default has active endpoints, at ang solusyon ay i-stop o i-remove ang container na nakakabit pa rito.

Kung bago sa iyo ang Compose, makatutulong na basahin muna ang layout ng Compose file at mga lifecycle command, dahil ipinapalagay ng lahat ng sumusunod na kaya mong mag-start at mag-stop ng project.

DNS ayon sa service name ang madalas mapalampas ng mga beginner

Sa anumang user-defined network, nagpapatakbo ang Docker ng naka-embed na DNS server na nakikita ng bawat container sa 127.0.0.11. Nireresolba nito ang mga service name sa kasalukuyang address ng mga container. Kaya naaabot ng web ang database gamit ang hostname na db, sa port 5432, nang walang kailangang configuration.

docker compose exec web getent hosts db

Nagpi-print ito ng linyang gaya ng 172.18.0.2 db. Kung walang output, wala sa iisang network ang dalawang service.

Ang pagkakamaling halos lahat ay nagagawa kahit isang beses ay ang paggamit ng localhost sa application config. Sa loob ng container, ang localhost ay ang container mismo, hindi ang host at hindi ang ibang service. Malinaw itong iniuulat ng mga Postgres client:

could not connect to server: Connection refused
	Is the server running on host "localhost" (127.0.0.1) and accepting
	TCP connections on port 5432?

Dapat ay postgresql://postgres:example@db:5432/postgres ang connection string. Ang service name ang inilalagay sa host part.

May dalawang detalye na makakatipid ng oras sa hinaharap. Nireresolba ang mga name batay sa kasalukuyang tumatakbo, kaya ang docker compose up -d --scale web=3 ay nagbibigay ng isang name na may tatlong address. Kung walang expiration ang DNS cache ng client, maituturo nito ang sarili sa dead container. At ang legacy na bridge network na ginagamit ng plain docker run nang walang --network ay walang name resolution. Ito ang dahilan kung bakit hindi tugma sa nakikita mo ang mga lumang payo tungkol sa container links mula 2016.

Hindi kailangan ang ports: para pagdugtungin ang dalawang serbisyo

Ang ports: ay nagpa-publish ng container port sa host. Para ito sa traffic na dumarating mula sa labas ng Docker. Wala itong kinalaman sa traffic sa pagitan ng mga serbisyo, na gumagana na sa buong port range sa project network.

Kaya walang naitutulong ang ports: - "5432:5432" na idinadagdag ng maraming tao sa kanilang database service, at nagdudulot pa ito ng tunay na panganib: inilalantad nito ang Postgres sa public interface ng server. Tanggalin ito. Kung kailangan itong maabot mula sa iyong laptop para sa isang migration, i-bind ito sa loopback gamit ang "127.0.0.1:5432:5432" at i-access ito sa pamamagitan ng SSH tunnel. Ipinaliliwanag sa kung paano gumagana ang mga port at listening service sa Linux ang pagkakaiba ng listening socket, published port, at firewall rule.

Documentation lamang ang expose: sa ilalim ng Compose. Wala itong binubuksan dahil walang isinara sa pagitan ng mga container na nasa iisang network.

Kung kailan angkop ang network_mode host, at ang kapalit nito

Inaalis ng host mode ang sariling network namespace ng container at direktang ginagamit ng process ang mga interface ng host.

services:
  probe:
    image: alpine:3.20
    network_mode: host
    command: sleep infinity

May mga lehitimong dahilan para gamitin ito. Ang process na kailangang makakita ng broadcast o multicast traffic sa local network, gaya ng device discovery para sa media server o home automation hub, ay hindi ito makikita sa likod ng bridge dahil hindi ipinapasa ng bridge ang traffic na iyon sa container. Kailangan naman ng monitoring agent na nagbabasa ng interface counters ng host ang mga interface ng host. Nalalaktawan din ang address translation hop, na mahalaga kapag mataas ang packet rate.

Partikular ang mga kapalit nito.

ports: ay hindi na gumagana. Nagbababala ang Docker na itinatapon ang published ports kapag ginagamit ang host network mode, at nagbi-bind ang container sa anumang bina-bind ng process nito. Kapag may dalawang host mode container na parehong gustong gumamit ng port 8080, magkakaroon ng conflict at mamamatay ang pangalawa na may bind: address already in use.

Nawawala sa parehong direksiyon ang name resolution gamit ang service name. Wala ang container sa project network, kaya hindi nito ma-resolve ang db, at hindi rin ito ma-resolve ng ibang services. Maaabot lamang nito ang mga iyon sa pamamagitan ng mga port na naka-publish sa host, karaniwan sa 127.0.0.1.

Nawawala ang isolation. Ang process na nagba-bind sa 0.0.0.0 sa loob ng host mode container ay nakikinig sa lahat ng interface ng server, kasama ang public interface, tulad mismo ng package na ini-install gamit ang apt. May isang pakinabang dito: dumaraan ang traffic na ito sa normal na input path, kaya naa-apply rito ang mga UFW rule, hindi gaya ng published ports.

Feature ng Linux Docker Engine ang host mode. Sinusuportahan lamang ito ng Docker Desktop mula version 4.34 pataas at pagkatapos mo itong i-enable. May dagdag na limitasyon: hindi maaaring mag-bind ang mga container sa host IP addresses, at TCP at UDP lamang ang pinangangasiwaan. Kung kalahati ng team mo ay gumagamit ng Linux servers at ang kalahati ay Docker Desktop, asahang magkakaiba ang behavior ng iisang file.

Gamitin ang host mode kapag kailangan mo ang mga interface ng host. Huwag itong gamitin para ayusin ang connection problem, dahil kadalasan ay pinapalitan lamang nito ang isang problema ng mas mahirap na problema.

Ikonekta ang dalawang Compose project gamit ang external network

Hindi nakikita ng isang project ang network na ginawa ng isa pang project. Kaya hindi makita ng reverse proxy sa proxy/compose.yaml ang app sa app/compose.yaml, kahit nasa iisang server ang mga ito. Ang solusyon ay isang network na hindi pagmamay-ari ng alinmang project.

Manu-mano itong likhain nang isang beses:

docker network create edge

Pagkatapos, ideklara itong external sa bawat project. Para sa proxy:

services:
  proxy:
    image: traefik:v3.1
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - edge

networks:
  edge:
    name: edge
    external: true

Para sa application:

services:
  app:
    image: nginx:1.27
    networks:
      - edge
      - internal
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: example
    networks:
      - internal

networks:
  edge:
    name: edge
    external: true
  internal:

Sinasabi ng external: true sa Compose na kumonekta sa isang umiiral nang network sa halip na lumikha ng bago, at huwag itong alisin sa docker compose down. Mas mahalaga kaysa sa inaakala ang hiwalay na name: key: kung wala ito, hahanapin ng Compose ang network na eksaktong may pangalang edge. Kapag ginamit ito, maaari mong ibang pangalan ang gamitin sa file at sa host.

Kung hindi umiiral ang network, tatangging magsimula ang Compose at iuulat nito na idineklarang external ang network ngunit hindi ito makita. Likhain muna ito.

Pansinin ang ginagawa ng application file sa internal. Nasa project-local network lamang ang database, kaya hindi ito maaabot ng proxy at app lamang ang maaaring kumonekta rito. Kapag idinagdag ang internal: true sa ilalim ng isang network, tuluyan ding inaalis ang route nito patungo sa labas ng network. Magandang default ito para sa database, pero may isang mahalagang epekto: hindi makapagda-download ng anuman ang container sa internal network. Kaya magha-hang at mauuwi sa timeout ang entrypoint na nagpapatakbo ng apt-get update o pip install sa startup.

Para sa kumpletong setup na may routing rules at certificates, tingnan ang pagpapatakbo ng maraming app sa likod ng isang Traefik instance.

Mga published port ay lumalampas sa UFW

Ito ang bahagi ng Compose networking na nagiging security incident. Nag-publish ka ng port, sinuri mong active ang UFW at dini-deny nito ang lahat maliban sa SSH, pero naa-access pa rin mula sa internet ang service.

sudo ufw status
curl http://203.0.113.10:8080

Sinasabi ng UFW na blocked ang port. Gayunman, ibinabalik pa rin ng curl ang page. Walang sira. Direktang nagsusulat ang Docker ng sarili nitong address translation at forwarding rules sa iptables. Ipinapasa ang traffic papunta sa published container port sa container sa halip na ihatid sa host. Kaya hindi ito dumadaan sa chain na minamanage ng UFW para sa traffic na lokal na nakalaan sa host. Nauuna ring tumugma ang rules ng Docker bago ang rules ng UFW.

Ang maikling solusyon ay i-publish lamang ang port kung saan ito kailangan:

    ports:
      - "127.0.0.1:8080:80"

Itinatali nito ang host side sa loopback. Dahil dito, naa-access ang port mula mismo sa server at sa pamamagitan ng SSH tunnel, pero hindi mula sa ibang lugar. Ilagay sa likod ng reverse proxy ang public entry point, at sadyang i-publish doon ang 80 at 443. Nasa kung bakit dumadaan ang Docker diretso lampas sa UFW at kung paano ito ayusin ang buong paliwanag, kasama ang DOCKER-USER chain para sa mga sitwasyong kailangan mong mag-filter ng published port.

Paano ito i-debug gamit ang apat na command

Magsimula sa pagtukoy kung saang network talaga nakakonekta ang bawat container:

docker network inspect shop_default

Inililista ng Containers block ang lahat ng nakakonektang container kasama ang address ng mga ito. Ang service na wala sa listahang iyon ay nasa ibang network, gumagamit ng host mode, o hindi tumatakbo.

I-test ang name resolution mula sa isang pansamantalang container na nakakonekta sa parehong network. Sa ganitong paraan, hindi mo kailangang mag-install ng tooling sa sarili mong images:

docker run --rm --network shop_default busybox nslookup db
docker run --rm --network shop_default busybox nc -zv db 5432

Ang pag-fail ng nslookup ay tumutukoy sa problema sa name resolution o network membership. Kung nagso-succeed ang nslookup habang nagfa-fail ang nc, tumatakbo ang service pero hindi ito nakikinig sa port na iyon, o nakikinig ito sa 127.0.0.1 sa loob ng sarili nitong container sa halip na sa 0.0.0.0. Karaniwan ito sa mga development server. Ang ayos ay nasa bind address ng application, hindi sa Docker.

May isa pang failure na maaaring mapagkamalang Docker bug. Kung nakakapag-communicate ang mga container sa isa't isa pero hindi sila makakonekta sa machine sa office o VPN network, malamang na nag-o-overlap ang Docker subnet sa network na iyon. Bilang default, nag-a-allocate ang Docker mula sa 172.17.0.0/16 pataas. Ilipat ang pool sa /etc/docker/daemon.json:

{
  "default-address-pools": [
    { "base": "10.200.0.0/16", "size": 24 }
  ]
}

Pagkatapos, patakbuhin ang sudo systemctl restart docker at i-recreate ang mga apektadong network, dahil pinananatili ng existing network ang subnet na ginamit noong ginawa ito.

FAQ

Bakit hindi maabot ng mga container ang isa’t isa gamit ang service name?

Hindi sila nasa iisang network. Awtomatikong inilalagay ng Compose ang bawat service sa <project>_default, pero kapag nagdagdag ka ng networks: list sa isang service, iyon na ang kumpletong set ng mga network nito at hindi na awtomatikong isinasama ang default. Patakbuhin ang docker network inspect <network> at tingnan kung lumilitaw ang parehong container sa Containers block. Tiyakin ding walang service ang gumagamit ng network_mode: host, dahil ang container na nasa host mode ay walang Docker network at hindi nito mare-resolve ang mga service name.

Kailangan ko bang mag-publish ng ports para maabot ng isang service ang isa pa?

Hindi. Sa isang Compose network, maaabot ng ibang container sa network ang bawat port ng lahat ng container. Ang ports: ay para lamang ilantad ang isang container sa traffic mula sa labas ng Docker, at ang expose: ay documentation lamang. Karaniwan at magastos na gawain ang pag-publish ng database port, dahil inilalagay nito ang database sa public interface ng server.

Ano ang pagkakaiba ng bridge at host networking?

Binibigyan ng bridge ang container ng sarili nitong network namespace at address sa isang virtual switch, kasama ang awtomatikong name resolution sa pagitan ng mga container at translated outbound traffic. Direktang ginagamit ng host ng container ang network stack ng host: walang hiwalay na address, walang resolution gamit ang service name, walang port publishing, at walang isolation mula sa iba pang listener ng host. Ang bridge ang default at tamang gamitin maliban kung kailangan ng process ang mga interface ng host.

Paano ko ikokonekta ang mga container mula sa dalawang magkaibang Compose file?

Gumawa ng shared network gamit ang docker network create edge, pagkatapos ay ideklara ito sa parehong file gamit ang external: true at i-attach ang mga service na kailangang makipag-ugnayan. Hindi ito gagawin o buburahin ng Compose. Kung lalaktawan mo ang create step, tatanggi ang Compose na magsimula at iuulat na external ang network ayon sa declaration pero hindi ito natagpuan.

Bakit naaabot mula sa internet ang container ko kahit hinaharangan ng UFW ang port?

Dahil pinangangasiwaan ang published port ng forwarding rules na idinadagdag ng Docker sa iptables. Mina-match ang mga rule na ito bago ang mga rule ng UFW, at hindi dumadaan ang forwarded traffic sa chain na fina-filter ng UFW. I-bind ang host side sa loopback gamit ang "127.0.0.1:8080:80" at ilagay ang anumang public service sa likod ng reverse proxy sa ports 80 at 443.