Uruchamiasz aplikację w kontenerze, ale przeglądarka na hoście nie może połączyć się z usługą? Najczęściej trzeba opublikować port kontenera, choć sam wpis `-p` nie wystarczy, jeśli aplikacja nasłuchuje tylko na swoim lokalnym interfejsie.

Port hosta kieruje ruch do portu kontenera, ale adres nasłuchiwania decyduje, kto się połączy
- `-p HOST:KONTENER` ustawia przekierowanie, na przykład z portu 8080 hosta na port 80 kontenera.
- `docker port` pokazuje mapowania działającego kontenera, a `docker ps` pozwala szybko je przejrzeć.
- Bez podania adresu hosta publikowany port domyślnie nasłuchuje na wszystkich interfejsach.
- `EXPOSE` nie publikuje portu na hoście. To informacja o porcie obrazu.
- Do pracy lokalnej przypisz port do `127.0.0.1`, jeśli nie ma być dostępny z innych urządzeń.
W zapisie `-p 8080:80` po lewej stronie jest host
Zapis wygląda niewinnie, ale łatwo odczytać go odwrotnie. W poleceniu docker run -p 8080:80 nginx pierwsza liczba oznacza port komputera hosta, a druga port w kontenerze. Ruch kierowany na port 8080 hosta Docker przekazuje do portu 80 kontenera.
Mapowanie działa, gdy w kontenerze faktycznie działa usługa nasłuchująca na wskazanym porcie. Jeśli serwer aplikacji używa portu 3000, przekierowanie powinno wskazywać właśnie 3000 po stronie kontenera, nawet jeśli na hoście wybierzesz inną wartość. Samo opublikowanie portu nie uruchamia serwera.
Dokumentacja Docker dotycząca publikowania portów opisuje ten mechanizm jako przekierowanie ruchu między portem hosta a portem kontenera. W praktyce możesz więc użyć portu 8080 na hoście, choć aplikacja w kontenerze oczekuje połączeń na porcie 3000.
Adres `127.0.0.1` ogranicza dostęp do hosta
Domyślnie mapowanie takie jak -p 8080:80 udostępnia port na wszystkich interfejsach hosta, czyli zwykle pod adresem `0.0.0.0`. To wygodne, gdy aplikacja ma być osiągalna z sieci, ale łatwo w ten sposób wystawić usługę, która miała działać wyłącznie lokalnie.
Do testów na własnym komputerze użyj docker run -p 127.0.0.1:8080:80 nginx. Wtedy połączenie z portem 8080 jest przypisane do interfejsu loopback. W Docker Compose analogiczny zapis może wyglądać tak:
services:
web:
image: nginx
ports:
- "127.0.0.1:8080:80"Jeśli usługa ma być dostępna z innych maszyn, wybór adresu musi pasować do zamierzonego dostępu, a konfigurację trzeba ocenić razem z regułami sieci i zaporą. Sam wpis portu z adresem `127.0.0.1` ogranicza dostęp zdalny, ale nie zastępuje przemyślanej konfiguracji całego środowiska.
`EXPOSE` opisuje port, ale nie otwiera go na hoście
W Dockerfile możesz zobaczyć instrukcję EXPOSE 80 i uznać, że port jest już dostępny z przeglądarki. Nie jest. `EXPOSE` dokumentuje port, którego używa kontener, ale samo nie tworzy mapowania na hoście.
Do udostępnienia portu przy uruchamianiu służy `-p`, na przykład docker run -p 8080:80 nginx. Z kolei opcja -P publikuje porty zadeklarowane jako exposed na losowo wybranych portach hosta. Ponieważ wynik może być mniej oczywisty, po starcie sprawdź go poleceniem docker ps albo `docker port`.
Jest tu jeszcze częsta pułapka: kontener może mieć prawidłowe mapowanie, a aplikacja nadal będzie nieosiągalna, jeśli nasłuchuje wyłącznie na `127.0.0.1` wewnątrz kontenera. Zwykle proces powinien nasłuchiwać na interfejsie dostępnym w kontenerze, często `0.0.0.0`, a ograniczenie dostępu ustawia się po stronie publikacji portu.
Wynik `docker port` zawęża diagnozę do mapowania
Gdy kontener już działa, polecenie docker port NAZWA_KONTENERA pokaże przypisane porty. Możesz też wskazać port wewnętrzny, na przykład docker port web 80/tcp. To szybki sposób, by sprawdzić, czy Docker publikuje oczekiwany port i pod jakim adresem hosta.
Dokumentacja polecenia `docker container port` wskazuje, że komenda wyświetla mapowania albo wybrane mapowanie dla konkretnego kontenera. Wynik `0.0.0.0:8080` oznacza nasłuchiwanie na wszystkich interfejsach hosta; `127.0.0.1:8080` wskazuje dostęp lokalny.
| Sytuacja | Prawdopodobna przyczyna | Co zrobić |
|---|---|---|
| Przeglądarka hosta nie łączy się, a `docker port` nic nie zwraca | Port nie został opublikowany przy tworzeniu kontenera | Utwórz kontener ponownie z właściwym `-p` lub wpisem `ports` w Compose. |
| Mapowanie jest widoczne, lecz aplikacja nie odpowiada | Usługa nie działa, używa innego portu albo nasłuchuje wyłącznie na loopback kontenera | Sprawdź logi i konfigurację nasłuchiwania aplikacji oraz zgodność portu kontenera. |
| Port hosta jest już zajęty | Inny proces lub kontener korzysta z tego samego portu hosta | Wybierz inny port po stronie hosta, pozostawiając właściwy port kontenera. |
| Kontener działa, ale połączenie z innej maszyny nie działa | Port przypisano do `127.0.0.1` albo ruch blokuje sieć lub zapora | Sprawdź adres publikacji, reguły zapory i trasę sieciową, zanim zmienisz mapowanie na `0.0.0.0`. |
W razie niezgodności zacznij od porównania trzech rzeczy: portu hosta, portu kontenera i adresu nasłuchiwania. To zwykle szybciej wskazuje problem niż ponowne uruchamianie kontenera bez zmiany konfiguracji.
Jedno mapowanie lokalne chroni bazę przed przypadkowym wystawieniem
Załóżmy, że lokalna aplikacja ma łączyć się z bazą danych w kontenerze na porcie 5432, a do hosta chcesz dostać się przez port 15432. Mapowanie 127.0.0.1:15432:5432 pozwoli korzystać z bazy z hosta, bez domyślnego publikowania jej na wszystkich interfejsach.
To wybór, który sam bym rozważył dla lokalnej bazy deweloperskiej: port bazy zostaje dostępny dla hosta, lecz nie jest bez potrzeby wystawiany na interfejsy sieciowe. Jeśli do bazy mają łączyć się inne kontenery w tej samej sieci Docker, publikowanie portu hosta może w ogóle nie być potrzebne. Kontenery mogą komunikować się po nazwie usługi i porcie wewnętrznym.
Nie zakładaj też, że słowo „localhost” zawsze rozwiązuje temat bezpieczeństwa. Dokumentacja Docker odnotowuje, że w wydaniach starszych niż 28.0.0 inne urządzenia w tym samym segmencie warstwy drugiej mogły w określonych warunkach dotrzeć do portów opublikowanych na localhost. Przy starszym środowisku albo nietypowej konfiguracji sieci sprawdź wersję i zasady dostępu, zamiast traktować samo `127.0.0.1` jako uniwersalną gwarancję.
Przed publikacją portu ustal, kto ma się łączyć
Najpierw zdecyduj, czy potrzebujesz dostępu tylko z hosta, z innych kontenerów, czy również z sieci. Dla połączenia lokalnego przypisz port do `127.0.0.1`; dla komunikacji między kontenerami sprawdź, czy wystarczy wspólna sieć Docker; publiczną dostępność konfiguruj świadomie, z uwzględnieniem zapory i uwierzytelniania.
Mapowanie portu mówi, którędy popłynie ruch, nie kto powinien go otrzymać. Gdy przeglądarka nie łączy się z aplikacją, sprawdź port wewnętrzny i adres nasłuchiwania. Gdy działa, ale usługa jest osiągalna zbyt szeroko, popraw adres publikacji, zanim problem zamieni się w niepotrzebnie otwarty dostęp.
