Skip to content
VDS · Docker i kontejneri

Docker mreže i prosleđivanje portova

Kako kontejneri vide jedni druge, kako se objavljivanje porta razlikuje od običnog EXPOSE i zašto Docker zaobilazi ufw pravila.

Ažurirano 23. avgust 2026.

Pola problema sa kontejnerima je mrežne prirode: servis ne može da dođe do baze, port je zauzet, panel je odjednom izložen celom internetu. Hajde da razložimo kako to funkcioniše.

Tri tipa mreža

  • bridge — podrazumevani. Kontejneri dobijaju interne adrese i komuniciraju međusobno; napolje izlaze kroz NAT hosta.
  • host — kontejner direktno koristi mrežu hosta; objavljivanje portova nije potrebno niti radi. Brzo, ali bez izolacije: port 80 kontejnera je port 80 hosta.
  • none — nema mreže uopšte. Za zadatke kojima ona ne treba.

Prilagođena mreža koju napraviš ti ili Compose razlikuje se od podrazumevanog bridge po jednoj važnoj stvari: u njoj radi razrešavanje imena. Kontejner app može da dođe do kontejnera db po imenu db.

docker network create backend
docker network ls
docker network inspect backend

U Compose-u se takva mreža automatski pravi za svaki projekat.

Objavljivanje portova

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

Levo je port na hostu, desno je port unutar kontejnera. Direktiva EXPOSE u imidžu ne objavljuje ništa: to je samo napomena o tome na kom portu aplikacija sluša.

Pravilo je jednostavno: objavi samo ono što mora da bude dostupno spolja. Baza, panel i interni API idu na 127.0.0.1, a veb server sa sertifikatom ih izlaže napolje.

Docker sam piše iptables pravila i to pre lanaca kojima upravlja ufw. Port objavljen kao -p 8080:8080 biće dostupan sa interneta čak i ako ufw prikazuje „deny”. Ne oslanjaj se na firewall — veži port na 127.0.0.1.

Komunikacija između kontejnera

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

networks:
  frontend:
  backend:

Ovde je baza dostupna samo aplikaciji, a samo veb server gleda napolje. To je ispravna konfiguracija za bilo koji stack.

Unutar kontejnera susedu pristupaš po imenu servisa: postgres://db:5432/app. Adresa localhost unutar kontejnera znači sam kontejner, ne host — druga najčešća greška posle latest.

Da iz kontejnera dođeš do servisa koji radi na samom hostu, koristi ime host.docker.internal tako što ćeš dodati:

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

Dijagnostika

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

ss će pokazati na kom interfejsu port zapravo sluša: 0.0.0.0:8080 — otvoren napolje, 127.0.0.1:8080 — nije.

Česte greške

  • „Port already in use”. Drži ga drugi kontejner ili servis na hostu. sudo ss -tulpn | grep :80 će naći krivca.
  • Kontejneri u različitim Compose projektima ne vide jedan drugog. Svaki projekat ima svoju mrežu. Poveži ih eksplicitno preko networks: { shared: { external: true } }.
  • Aplikacija sluša na 127.0.0.1 unutar kontejnera. Tada objavljivanje ne pomaže: ne možeš da joj priđeš spolja iz kontejnera. Podesi aplikaciju da sluša na 0.0.0.0.
  • Propusni opseg. Do 500 Mbps deljenih po hostu. Distribucija fajlova ga deli sa svim ostalim.