Wstęp
W dzisiejszym wpisie poruszymy temat, który jest absolutnie kluczowy dla każdego, kto chce swobodnie i profesjonalnie poruszać się w świecie Dockera. Mowa o sieciach. Na początku swojej drogi z konteneryzacją pewnie skupiasz się na budowaniu obrazów i uruchamianiu pojedynczych kontenerów. Ale co, gdy Twoja aplikacja składa się z kilku serwisów, które muszą ze sobą rozmawiać? Backend musi odpytać bazę danych, frontend musi zawołać backend, a do tego dochodzi jeszcze jakiś Redis do keszowania.
Zapewne nieraz złapałeś się na tym, że próbujesz połączyć te klocki, żonglując adresami IP, bawiąc się dziwnymi flagami, a na końcu i tak coś nie działa. Kontenery się nie widzą, porty się blokują, a frustracja rośnie. Znam to doskonale.
Na szczęście Docker dostarcza wbudowane narzędzia sieciowe, które pozwalają mieć kontrolę nad sieciami w kontenerach. W tym wpisie pokażę Ci, jak działają sieci w Dockerze, jakie masz możliwości konfiguracji i jak uniknąć najczęstszych problemów. Przedstawię praktyczne przykłady, które pomogą Ci zrozumieć, kiedy używać którego typu sieci i jak debugować problemy z komunikacją między kontenerami.
Sieci w dockerze – podstawy (docker network)
Na początek przyjrzyjmy się bliżej podstawą sieci w Dockerze. To właśnie od zrozumienia tych mechanizmów zależy, czy Twoje kontenery będą ze sobą sprawnie współpracować, czy też utkniesz na etapie debugowania połączeń.
Czym są sięci w dockerze?
Najprościej mówiąc, sieć w Dockerze to wirtualna sieć komputerowa (LAN) stworzona specjalnie dla Twoich kontenerów. Kiedy tworzysz taką sieć, Docker działa jak wirtualny router – przydziela kontenerom adresy IP, zarządza ruchem i pozwala im na komunikację.
Dzięki temu kontenery działające w tej samej sieci mogą się nawzajem „widzieć” i komunikować, tak jak komputery podłączone do tego samego routera w Twoim domu. Co więcej, są one domyślnie odizolowane od kontenerów działających w innych sieciach, co daje nam świetne narzędzie do porządkowania i zabezpieczania naszych aplikacji.
Typy sieci
Docker oferuje kilka typów sieci, każdy z różnym przeznaczeniem:
Bridge Network – To domyślny i najczęściej używany typ sieci. Kiedy instalujesz Dockera, automatycznie tworzona jest sieć o nazwie bridge
. Każdy kontener, który uruchomisz bez określania sieci, zostanie do niej podłączony. Kontenery na tej samej sieci bridge mogą się ze sobą komunikować po nazwie. Co ważniejsze, możesz tworzyć własne sieci typu bridge
, co jest zdecydowanie rekomendowaną praktyką.
Host Network – W tym trybie kontener nie dostaje własnego, izolowanego stosu sieciowego. Zamiast tego korzysta bezpośrednio z interfejsu sieciowego maszyny-hosta (np. z Twojego komputera, na którym uruchamiasz kontener). Oznacza to brak izolacji na poziomie sieci. Jeśli Twoja aplikacja w kontenerze nasłuchuje na porcie 8000
, będzie ona dostępna na porcie 8000
hosta, bez potrzeby mapowania portów. Daje to nieco lepszą wydajność, ale kosztem bezpieczeństwa i ryzyka konfliktów portów. Używaj go świadomie i tylko wtedy, gdy naprawdę musisz.
None Network – Jak sama nazwa wskazuje, kontener podłączony do tej sieci nie ma żadnego interfejsu sieciowego. Jest całkowicie odizolowany od świata. Przydaje się w bardzo specyficznych przypadkach, np. do uruchamiania zadań, które mają tylko przetwarzać dane i nie potrzebują żadnej komunikacji.
Overlay Network – To sieć przeznaczona do zastosowań w klastrach (grupa połączonych ze sobą komputerów, które ze sobą współpracują, aby działać jak jeden wspólny system), takich jak Docker Swarm czy Kubernetes. Pozwala kontenerom działającym na różnych maszynach-hostach komunikować się ze sobą tak, jakby były w jednej, płaskiej sieci. To temat na tyle duży, że można byłoby z tego zrobić cały osobny wpis.
Custom Bridge Networks – Pozwala przypisać kontenerowi adres MAC, dzięki czemu w sieci lokalnej wygląda on jak fizyczne urządzenie, a nie jak kontener schowany za hostem. Używane w bardziej zaawansowanych scenariuszach sieciowych.
Tworzenie własnych sieci
Domyślnie Docker tworzy kilka predefiniowanych sieci. Możesz je zobaczyć poleceniem:
docker network ls
Wynik będzie podobny do poniższego:

Na początek stwórzmy swoją pierwszą prostą sieć typu bridge
:
docker network create my-network
Teraz ponownie wyświetlając listę sieci dostaniemy naszą nowo utworzoną sieć:

Uruchomienie kontenera w sieci
Mamy już sieć, więc podłączmy do niej jakiś kontener. Użyjemy do tego flagi --network
. Uruchommy kontener z bazą danych PostgreSQL w naszej nowej sieci:
docker run -d --name mydb --network my-network -e POSTGRES_PASSWORD=sekretnehaslo postgres
Przeanalizujmy tę komendę:
-d
– Uruchamia kontener w tle (detached).--name mydb
– Nadajemy kontenerowi przyjazną nazwę. To bardzo ważne!--network my-network
– Podłączamy kontener do naszej sieci.-e POSTGRES_PASSWORD=...
– Zmienna środowiskowa wymagana przez obraz PostgreSQL.postgres
– Nazwa obrazu do uruchomienia.
Teraz nasz kontener mydb
działa wewnątrz sieci my-network
.
Mapowanie portów
W tej chwili nasza baza danych jest dostępna tylko dla innych kontenerów w tej samej sieci. Nie możemy się do niej podłączyć z naszej maszyny-hosta (np. przez DBeaver czy inne narzędzie). Aby to umożliwić, musimy zamapować port kontenera na port hosta.
Służy do tego flaga -p
(publish) w formacie PORT_HOSTA:PORT_KONTENERA
.
Zatrzymajmy i usuńmy poprzedni kontener, a następnie uruchommy go ponownie z mapowaniem portów:
docker stop mydb docker rm mydb docker run -d --name mydb --network my-network -p 5433:5432 -e POSTGRES_PASSWORD=sekretnehaslo postgres
Co się zmieniło? Dodaliśmy -p 5433:5432
. Oznacza to: „weź ruch przychodzący na port 5433
mojej maszyny-hosta i przekaż go na port 5432
wewnątrz kontenera mydb
„.
Dzięki temu możesz teraz połączyć się ze swoją bazą danych, używając adresu localhost:5433
.
Uwaga! Mapowanie portów jest potrzebne tylko wtedy, gdy chcesz uzyskać dostęp do usługi z zewnątrz sieci Dockera. Kontenery w tej samej sieci będą komunikować się ze sobą bezpośrednio, bez mapowania portów.
Podglądanie i inspekcja sieci (docker network inspect)
Często musimy sprawdzić, które kontenery są podłączone do danej sieci, albo jakie mają adresy IP. Do tego służy poniższa komenda:
docker network inspect my-network
W odpowiedzi dostaniemy informację o sieci w postaci JSON:
[ { "Name": "my-network", "Id": "99130b0e08c7f556f2488412124136dbcc933fd2c69a1189e2d00df45560c868", "Created": "2025-06-08T10:56:58.084759025Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.18.0.0/16", "Gateway": "172.18.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "63e1dfc9d319a967a246c85e62ae31f92b407a2206f23226b35c4a8deb352c48": { "Name": "mydb", "EndpointID": "844cce952dc8559d85180a575b8a33f24d6a70d64918da11268759aeccd35e49", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]
Z tego wyniku można odczytać:
- Jakie kontenery są podłączone do sieci
- Jakie mają adresy IP
- Konfigurację podsieci
- Ustawienia IPAM (IP Address Management)
A w naszym przypadku widzimy, że nasz kontener mydb
jest podłączony i ma wewnętrzny adres IP 172.18.0.2
. Moglibyśmy używać tego adresu do komunikacji, ale za chwilę zobaczysz znacznie lepszy sposób.
Więcej o sieciach w Dockerze
W tym punkcie dalej skupimy się na temacie sieci w Dockerze, ale tym razem pójdziemy o krok dalej. Zagłębimy się w bardziej zaawansowane aspekty. Tutaj skupimy się na praktycznych rozwiązaniach, które pozwolą lepiej izolować sieć środowiska, efektywniej zarządzać komunikacją i unikać typowych pułapek w codziennej pracy.
Dostęp po nazwie kontenera (DNS w Dockerze)
Gdy kontenery znajdują się w tej samej, stworzonej przez użytkownika sieci bridge
, Docker zapewnia automatyczne wykrywanie usług (service discovery) za pomocą wbudowanego serwera DNS.
Co to oznacza w praktyce? To, że nie musimy znać adresu IP kontenera. Możemy się do niego odwołać, używając jego nazwy.
Uruchommy 2 kontenery w tej samej sieci i następnie wejdźmy do jednego z naszych kontenerów:
# Tworzenie wspólnej sieci docker network create my-network # Tworzymy pierwszy kontener z bazą danych docker run -d --name my-database --network my-network -p 5433:5432 -e POSTGRES_PASSWORD=admin postgres # Tworzymy drugi kontener i wchodzimy od razu do konsoli docker run -it --network my-network --name my-backend alpine sh
Jesteśmy teraz wewnątrz powłoki kontenera my-backend
. Spróbujmy „pingnąć” naszą bazę danych po nazwie:
# Wewnątrz kontenera my-backend ping my-database
W rezultacie powinieneś dostać podobny wynik do poniższego:

To pokazuje, że Docker potrafi automatycznie tłumaczyć nazwę kontenera na jej wewnętrzy adres IP.
Uwaga! Ta funkcja nie działa w domyślnej sieci bridge
. To główny powód, dla którego powinieneś zawsze tworzyć własne sieci dla swoich projektów.
Izolacja środowisk – sieci projektowe
Wyobraź sobie, że pracujesz nad dwoma różnymi projektami. Każdy z nich używa bazy danych PostgreSQL na domyślnym porcie 5432
.
- Projekt A:
backend-a
,db-a
- Projekt B:
backend-b
,db-b
Jeśli uruchomisz wszystko w jednej, domyślnej sieci, zrobi się bałagan. Kontener backend-a
mógłby przez pomyłkę połączyć się z db-b
, jeśli nazwy byłyby podobne.
Znacznie lepszym podejściem jest stworzenie osobnej sieci dla każdego projektu:
docker network create projekt-a-net
docker network create projekt-b-net
Następnie uruchamiasz kontenery w dedykowanych im sieciach:
backend-a
idb-a
wprojekt-a-net
backend-b
idb-b
wprojekt-b-net
Dzięki temu kontenery z projektu A są całkowicie odizolowane od kontenerów z projektu B. Nie widzą się nawzajem i nie mogą się ze sobą komunikować. To zapewnia porządek, bezpieczeństwo i eliminuje ryzyko konfliktów.
Dobre praktyki i wskazówki dotyczące sieci
Z mojego doświadczenia wynika kilka zasad, których warto się trzymać:
- Dobrze jest używać własnych sieci
bridge
dla aplikacji wielokontenerowych. Nigdy nie powinniśmy polegać na domyślnej siecibridge
. Daje nam to DNS i izolację. - Warto pamiętać, żeby odpowiednio nazywać swoje kontenery i sieci np. nazwa sieci
my-project-net
jest lepsze niżsiec123
. Na początku może się to wydawać zbędne, ale jak ma się to dobrze poukładane to naprawdę potrafi ułatwić życie np. w debugowaniu.
Ewentualnie też można używać etykiet do lepszego opisu:docker network create --label project=myapp --label environment=dev dev-net
. - Dobrze jest też unikać sieci typu
host
, chyba że są ku temu dobre powody (np. aplikacja do monitoringu sieci, która musi widzieć cały ruch hosta) i też należy wiedzieć jakie to potencjalne konsekwencje może nieść m.in. temat bezpieczeństwa. - Nie warto mapować wszystkich portów jak leci, a robić to tylko wtedy, gdy potrzebujemy faktycznie dany port na zewnątrz. Jeśli backend komunikuje się z bazą danych, nie trzeba mapować portu bazy danych na hosta, chyba że chcemy mieć do niej dostęp z narzędzi deweloperskich (dla deweloperskich potrafi bardzo ułatwić życie).
Typowe problemy i najczęstsze pytania
W tym punkcie przyjrzymy się najczęstszym problemom oraz pytaniom związanym z sieciami w Dockerze. Dzięki temu łatwej będzie Ci uniknąć schematycznych problematycznych sytuacji, które niejednokrotnie potrafią marnować niepotrzebnie czas.
Kontenery się nie widzą – co może być nie tak?
Pingujesz kontener po nazwie i dostajesz bad address
lub ping: unknown host
:
- Czy kontenery są w tej samej sieci? Użyj
docker network inspect nazwa_sieci
i sprawdź, czy oba kontenery są na liścieContainers
. - Czy używasz własnej sieci
bridge
, a nie domyślnej? Pamiętaj, DNS po nazwie działa tylko w sieciach, które sam stworzyłeś. - Czy nie ma literówki w nazwie kontenera? Nazwa kontera
my-db
to nie to samo comy_db
. Sprawdź nazwy za pomocądocker ps
. - Czy firewall wewnątrz kontenera nie blokuje ruchu? Niektóre obrazy (np. z bardziej restrykcyjnymi systemami operacyjnymi) mogą mieć włączony firewall. Sprawdź konfigurację obrazu.
Konflikty portów, DNS, firewalle
Konflikty portów – Błąd Error starting userland proxy: listen tcp4 0.0.0.0:8080: bind: address already in use
jest jednoznaczny. Próbujesz zmapować kontener na port hosta (8080
), który jest już zajęty przez inny proces (inny kontener lub aplikację działającą bezpośrednio na hoście). Rozwiązania są dwa: zatrzymaj proces, który zajmuje port, albo zmapuj kontener na inny, wolny port (np. -p 8081:80
).
Problemy z DNS – Czasem, zwłaszcza w środowiskach korporacyjnych z własnymi serwerami DNS lub przy korzystaniu z VPN, Docker może mieć problem z rozwiązywaniem nazw, zarówno wewnętrznych, jak i zewnętrznych (np. przy próbie pobrania pakietów z internetu w trakcie budowania obrazu). Możesz skonfigurować, jakich serwerów DNS ma używać demon Dockera (edycja pliku /etc/docker/daemon.json
) lub przekazać serwer DNS bezpośrednio do kontenera za pomocą flagi --dns
.
Firewall – Pamiętaj, że ruch sieciowy Dockera (zwłaszcza ten zmapowany na porty) musi przejść przez firewall hosta. Reguły iptables
(na Linuksie) lub Windows Firewall mogą blokować komunikację. Docker stara się zarządzać iptables
automatycznie, ale czasem może dojść do konfliktów z innymi narzędziami (np. ufw
). Jeśli masz problemy z dostępem do zmapowanego portu z innej maszyny w sieci, sprawdź w pierwszej kolejności ustawienia firewalla na hoście Dockera.
*firewall to mechanizm bezpieczeństwa, który filtruje ruch sieciowy między komputerem (lub serwerem, kontenerem) a światem zewnętrznym, blokując lub przepuszczając połączenia zgodnie z ustalonymi regułami.
Porównanie sieci bridge i host
Cecha | Sieć bridge (własna) | Sieć host |
---|---|---|
Izolacja | Wysoka. Kontener ma własny stos sieciowy. | Brak. Kontener współdzieli stos sieciowy hosta. |
Bezpieczeństwo | Wyższe. Izolacja ogranicza potencjalne szkody. | Niższe. Proces w kontenerze ma dostęp do interfejsów sieciowych hosta. |
Komunikacja | Po nazwie kontenera (wbudowany DNS). | Bezpośrednio, tak jak procesy na hoście (np. przez localhost). |
Mapowanie Portów | Wymagane do wystawienia usług na zewnątrz (-p HOST:CONTAINER). | Niedostępne/Niepotrzebne. Aplikacja od razu bindowana jest na porcie hosta. |
Wydajność | Nieco niższa. Dodatkowa warstwa NAT/proxy. | Maksymalna. Brak narzutu sieciowego. |
Konflikty Portów | Łatwe do zarządzania (mapujesz na dowolny wolny port hosta). | Kontener musi używać portów, które nie są zajęte na hoście. |
Typowe Użycie | Domyślny wybór dla większości aplikacji wielokontenerowych. | Aplikacje wymagające wydajności sieciowej lub zarządzające wieloma portami (np. monitoring). |
Warto zaznaczyć, że w większości przypadków stosuję sieć bridge z własnymi nazwami, a host tylko do debugowania lub specyficznych integracji.
Zbiór przydatnych komend
Dla utrwalenia, oto mała ściągawka z najważniejszych komend dotyczących sieci:
docker network ls
– Wyświetla listę wszystkich sieci.docker network create <nazwa_sieci>
– Tworzy nową sieć (domyślniebridge
).docker network rm <nazwa_sieci>
– Usuwa sieć.docker network inspect <nazwa_sieci>
– Pokazuje szczegółowe informacje o sieci, w tym podłączone kontenery.docker network connect <nazwa_sieci> <nazwa_kontenera>
– Podłącza działający kontener do dodatkowej sieci.docker network disconnect <nazwa_sieci> <nazwa_kontenera>
– Odłącza kontener od sieci.docker run --network <nazwa_sieci> ...
– Uruchamia kontener w określonej sieci.docker run -p <port_hosta>:<port_kontenera> ...
– Mapuje port kontenera na port hosta.
Podsumowanie
Dotarliśmy do końca! Mam nadzieję, że ten wpis rozjaśnił Ci temat sieci w Dockerze. Jest to kluczowy element każdej architektury opartej na kontenerach. Dzięki nim zyskujemy elastyczność, izolację i łatwość zarządzania środowiskiem – niezależnie, czy budujesz system mikroserwisowy, czy zwykły zestaw narzędzi developerskich.
Opanowanie sieci to absolutny fundament, który otwiera drzwi do budowania skomplikowanych, ale jednocześnie uporządkowanych i przenośnych środowisk. To inwestycja, która zwraca się wielokrotnie w postaci mniejszej liczby problemów, łatwiejszego dewelopmentu i stabilniejszych wdrożeń.
Jeśli masz jakieś pytania, uwagi, albo chcesz podzielić się swoimi doświadczeniami z sieciami w Dockerze – śmiało pisz w komentarzach! Chętnie pomogę i podyskutuję.