Wstęp
Jeśli mieliście już okazję zapoznać się z podstawami konteneryzacji na moim blogu, to dzisiaj zrobimy krok naprzód, koncentrując się na praktycznych aspektach pracy z Dockerem oraz jego nieodzownym towarzyszem – Docker Hubem. Docker, dzięki swojej umiejętności pakowania aplikacji wraz z zależnościami w przenośne kontenery, stał się kluczowym narzędziem dla programisty i specjalisty DevOps, eliminując problemy z niespójnością środowisk.
Docker Hub działa jak centralne repozytorium dla obrazów Dockerowych – można je porównać do GitHuba dla kodu. To tutaj znajdziemy tysiące gotowych obrazów dla popularnych technologii, a także miejsce do publikowania i wersjonowania naszych własnych dzieł. Zapewnia to nie tylko spójność, ale także znacząco przyspiesza procesy deweloperskie i wdrożeniowe poprzez łatwy dostęp do sprawdzonych komponentów i możliwość współdzielenia własnych rozwiązań.
W tym artykule przyjrzymy się bliżej kluczowym komendom do zarządzania kontenerami, procesowi tworzenia własnych obrazów dzięki Dockerfile oraz efektywnemu wykorzystaniu Docker Huba do przechowywania i dystrybucji naszych aplikacji.
Podstawowe komendy do zarządzania kontenerami
Zacznijmy od praktyki. Aby efektywnie pracować z Dockerem, musimy poznać kilka podstawowych komend, które pozwolą nam zarządzać cyklem życia kontenerów.
docker ps
To prawdopodobnie jedna z najczęściej używanych komend. Służy do wyświetlania listy aktualnie uruchomionych kontenerów.
docker psWynik tej komendy pokaże nam m.in. ID kontenera, obraz, z którego został stworzony, uruchomioną komendę, czas działania, porty oraz nazwę kontenera.

Jeśli chcemy zobaczyć wszystkie kontenery, zarówno te działające, jak i zatrzymane, używamy flagi -a (all):
docker ps -a
To bardzo przydatne, gdy chcemy sprawdzić, jakie kontenery mieliśmy wcześniej uruchomione lub dlaczego jakiś kontener się zatrzymał.
Możemy też użyć flagi -q jeżeli chcemy wyświetlić tylko ID kontenerów:
docker ps -aq
docker start
Gdy mamy zatrzymany kontener, możemy go ponownie uruchomić dzięki komendy docker start, podając jego ID lub nazwę.
docker start <container_id_lub_nazwa>Jako przykład weźmy kontener z powyższego wyniku komendy docker ps -a:
docker start rabbitmq2docker run
To kluczowa komenda służąca do tworzenia i uruchamiania nowego kontenera z określonego obrazu. jeżeli obraz nie jest dostępny lokalnie, Docker automatycznie spróbuje go pobrać z Docker Hub.
Komenda docker run ma wiele przydatnych opcji, oto kilka najważniejszych:
- -d (detach) – Uruchamia kontener w tle (w trybie „detached”) i wyświetla jego ID. Bez tej flagi nasz terminal byłby „przywiązany” do kontenera i albo byśmy musieli sobie otworzyć nowy terminal do dalszej pracy albo zatrzymać kontener.
- -p <port_hosta>:<port_kontenera> (publish) – Mapuje port na hoście (naszym komputerze) na port wewnątrz kontenera np. -p 8080:80 przekieruje ruch z portu 8080 na naszym komputerze do portu 80 w kontenerze.
- --name <nazwa_kontenera> – Pozwala nadać kontenerowi własną, czytelną nazwę. jeżeli tego nie zrobimy, Docker nada losową nazwę.
- -it (interactive & tty) – Umożliwia interaktywną pracę z kontenerem, np. uruchomienie w nim powłoki shellowej.
- -v <ścieżka_hosta>:<ścieżka_kontenera> (volume) – Mapuje katalog z hosta do katalogu wewnątrz kontenera, co pozwala na trwałe przechowywanie danych lub udostępnianie plików np. -v /host/path:/container/path
- -e <zmienna>=<wartość> (environment) – Ustawia zmienne środowiskowe wewnątrz kontenera np. -e VARIABLE=value
Przykład uruchomienia kontenera z serwerem Nginx, działającego w tle, z mapowaniem portu 8080 na port 80 kontenera i nadaniem mu nazwy moj-server:
docker run -d -p 8080:80 --name moj-server nginxPo wykonaniu tej komendy, otwierając przeglądarkę pod adresem http://localhost:8080, powinniśmy zobaczyć domyślną stronę Nginx.
docker stop
Aby zatrzymać działający kontener, używamy komendy docker stop, podając jego ID lub nazwę.
docker stop <container_id_lub_nazwa>Na przykład, aby zatrzymać nasz kontener moj-server:
docker stop moj-serverTa komenda wysyła sygnał SIGTERM do głównego procesu w kontenerze, dając mu szansę na „grzeczne” zakończenie działania. jeżeli proces nie zareaguje w ciągu domyślnego czasu (zwykle 10 sekund), Docker wysyła sygnał SIGKILL.
docker rm
Zatrzymane kontenery przez cały czas istnieją w systemie i zajmują miejsce na dysku. Aby je usunąć, używamy komendy docker rm.
docker rm <container_id_lub_nazwa>Jeśli chcemy usunąć kontener, który przez cały czas działa, musimy go najpierw zatrzymać lub użyć flagi -f (force), która wymusi jego zatrzymanie i usunięcie: docker rm -f <container_id lub nazwa>.
docker logs
Podczas pracy z kontenerami, zwłaszcza tymi działającymi w tle, często chcemy zobaczyć, co się w nich dzieje – jakie komunikaty wypisuje aplikacja. Do tego służy komenda docker logs.
docker logs <container_id_lub_nazwa>Przydatne opcje:
- -f (follow) – Wyświetla logi na bieżąco, podobnie jak tail -f w Linuksie.
- --tail <liczba_linii> – Wyświetla określoną liczbę ostatnich linii logów.
Przykład:
docker logs -f moj-serverdocker images
Ta komenda wyświetla listę obrazów Dockerowych, które mamy pobrane lokalnie na naszym komputerze: docker images. Po wywołaniu zobaczymy informacje takie jak nazwa repozytorium obrazu, tag (wersja), ID obrazu, data utworzenia i rozmiar.

docker exec
Czasami potrzebujemy wykonać jakąś komendę wewnątrz już działającego kontenera. Może to być np. uruchomienie powłoki shellowej, aby „wejść” do kontenera i sprawdzić jego stan, pliki itp. Do tego służy docker exec.
docker exec [OPCJE] <container_id_lub_nazwa> <komenda>Najczęściej używaną opcją jest -it, która pozwala na interaktywną sesję. Na przykład, aby uruchomić powłokę bash w kontenerze o nazwie moj-server:
docker exec -it web-server bashPo wykonaniu tej komendy znajdziemy się wewnątrz kontenera i będziemy mogli wykonywać w nim standardowe polecenia Linuksowe. Aby wyjść z powłoki kontenera, wystarczy wpisać exit.
Skrócona wersja z listą komend Dockera
Poniżej wypisałem kilka podstawowych komend związanych z pracą z Dockerem z poziomu konsoli:
- docker ps – Wyświetlenie wszystkich uruchomionych kontenerów
- docker ps -a – Wyświetlenie wszystkich kontenerów (również zatrzymanych)
- docker images – Wyświetlenie wszystkich obrazów dostępnych lokalnie
- docker pull [image] – Pobranie obrazu z DockerHub
- docker run [options] [image] – Uruchomienie kontenera
- docker stop [container_name] – Zatrzymanie kontenera
- docker rm [container_name] – Usunięcie kontenera
- docker rmi [image] – Usunięcie obrazu
- docker logs [container_name] – Wyświetlenie logów kontenera
- docker exec -it [container_name] [command] – Wykonanie komendy w działającym kontenerze np. wejście do konsoli kontenera: docker exec -it my-nginx bash
Pamiętajcie, iż każda z tych komend ma wiele dodatkowych opcji. Zawsze możecie sprawdzić je, dodając --help na końcu komendy, np. docker run --help. Również można zajrzeć do oficjalnej dokumentacji Dockera.
Tworzenia własnych obrazów
Pobieranie gotowych obrazów z Docker Hub jest super wygodne, ale prędzej czy później będziemy chcieli stworzyć własny obraz dla naszej aplikacji. Do tego służy specjalny plik tekstowy o nazwie Dockerfile.
Podstawy Dockerfile
Dockerfile to plik tekstowy, który zawiera instrukcje dotyczące tego, jak zbudować obraz Dockera. Typowy Dockerfile zawiera instrukcje takie jak:
- FROM – bazowy obraz, na którym budujemy
- WORKDIR – ustawia katalog roboczy w kontenerze
- COPY / ADD – kopiuje pliki z hosta do kontenera
- RUN – wykonuje komendy podczas budowania obrazu
- ENV – ustawia zmienne środowiskowe
- EXPOSE – informuje, które porty będą nasłuchiwać
- CMD / ENTRYPOINT – określa, co ma być wykonane przy uruchomieniu kontenera
Przykład prostego Dockerfile dla aplikacji Spring Boot:
# Używamy oficjalnego obrazu OpenJDK 21 w wersji slim jako bazę FROM openjdk:21-slim # Ustawiamy katalog roboczy w kontenerze WORKDIR /app # Kopiujemy spakowaną aplikację (plik .jar) do katalogu roboczego w kontenerze COPY target/moj-app-1.0.0.jar app.jar # Informujemy Dockera, iż aplikacja będzie nasłuchiwać na porcie 8080 EXPOSE 8080 # Komenda, która zostanie wykonana podczas uruchamiania kontenera ENTRYPOINT ["java", "-jar", "app.jar"]Każda instrukcja w Dockerfile tworzy nową warstwę w obrazie. Warstwowa struktura obrazów Dockera pozwala na efektywne wykorzystanie pamięci i szybsze budowanie obrazów, ponieważ warstwy są buforowane.
Budowanie obrazu
Gdy mamy już gotowy Dockerfile, możemy zbudować z niego obraz dzięki komendy docker build. Komendę tę wykonujemy w katalogu, gdzie znajduje się nasz Dockerfile.
docker build -t my-app:1.0 .W powyższym przykładzie:
- -t my-app:1.0 oznacza tag (nazwę i wersję) dla naszego obrazu
- . to ścieżka do kontekstu budowania (w tym przypadku bieżący katalog)
Podczas budowania Docker przetworzy każdą instrukcję z Dockerfile, tworząc kolejne warstwy obrazu. Zobaczymy w konsoli logi z tego procesu. jeżeli wszystko pójdzie dobrze, po zakończeniu nasz nowy obraz pojawi się na liście po wykonaniu docker images.
Uruchamianie własnego obrazu
Po zbudowaniu obrazu możemy go uruchomić tak samo, jak każdy inny obraz pobrany z Docker Hub, używając komendy docker run.
docker run -d -p 8080:8080 --name my-running-app my-app:1.0W tym przypadku mapujemy port 8080 na hoście do portu 8080 w kontenerze (zgodnie z EXPOSE w naszym Dockerfile).
Docker Hub – centrum obrazów Dockera
Mamy już podstawy zarządzania kontenerami i tworzenia własnych obrazów. Teraz czas przyjrzeć się bliżej Docker Hub – miejscu, gdzie możemy znaleźć gotowe obrazy i dzielić się naszymi.
Czym jest Docker Hub
Docker Hub (hub.docker.com) to publiczne, chmurowe repozytorium obrazów Dockerowych. Można je porównać do GitHuba dla kodu źródłowego. Znajdziemy tam:
- Oficjalne obrazy (Official Images) – Obrazy popularnych systemów operacyjnych, języków programowania, baz danych i aplikacji, utrzymywane i weryfikowane przez dostawców systemu lub społeczność Dockera. Są one zwykle dobrze udokumentowane, regularnie aktualizowane pod kątem bezpieczeństwa i stanowią dobry punkt wyjścia.
- Obrazy od społeczności (Community Images) – Obrazy tworzone i udostępniane przez użytkowników Docker Huba. Mogą być bardzo przydatne, ale warto zwracać uwagę na ich popularność, liczbę pobrań, ostatnie aktualizacje i ewentualne luki bezpieczeństwa.
- Repozytoria prywatne (Private Repositories) – Docker Hub oferuje również możliwość przechowywania obrazów w repozytoriach prywatnych, które nie są publicznie dostępne. Jest to przydatne dla firm, które chcą przechowywać swoje własne, wewnętrzne obrazy. Tylko trzeba wziąć pod uwagę, iż darmowe konta mają ograniczoną liczbę prywatnych repozytoriów.
Jak wyszukiwać obrazy
Obrazy możemy wyszukiwać na kilka sposobów:
- Oczywiście przez stronę DockerHub. Wystarczy na stronie skorzystać z paska do wyszukiwania. Możemy filtrować wyniki, np. tylko oficjalne obrazy.
- Możemy też wpisać frazę w wyszukiwarce Google: dockerhub <nazwa obrazu>, gdzie nazwa obrazu to może być dowolne interesujące nas narzędzie np. dockerhub java.
- Mamy możliwość też wyszukiwania obrazów z poziomu terminalu z użyciem komendy docker search. Wynik pokaże nam nazwę obrazu, opis, liczbę gwiazdek (popularność), status (czy jest oficjalny).

W powyższym przykładzie wyszukujemy obrazów z frazą openjdk, gdzie obraz ma co najmniej 3 gwiazdki (ang. stars). Dodatkowo używamy opcji --no-trunc, żeby nie obcinał opisu obrazu.
Jak pobierać obrazy
Do pobierania obrazów z Docker Huba (lub innego rejestru) służy komenda docker pull.
docker pull <nazwa_obrazu>[:<tag>]Jeśli nie podamy tagu, Docker domyślnie pobierze obraz z tagiem latest. Dlatego chcąc pobrać docker pull nginx:latest możemy pomijać wersję taga i tylko wykonać: docker pull ngnix. Natomiast jak chcemy konkretną wersję pobrać to musimy wtedy wskazać o jaką wersję nam chodzi: docker pull nginx: docker pull nginx:1.28.0. Wszystkie informację o wersjach również mamy dostępne z samego docker huba, wysztarczy wejść na stronie na interesujący nas obraz (lista wersji dla nginx).

Po pobraniu obrazu, pojawi się on na liście docker images. Warto pamiętać, iż komenda docker run również automatycznie pobierze obraz, jeżeli nie znajdzie go lokalnie.
Oficjalne vs community images
Jak już wspomniałem, w Docker Hub znajdziemy dwa główne typy obrazów:
- Oficjalne obrazy (Official Images):
- Są oznaczone specjalną etykietą „Official Image”.
- Są weryfikowane przez Docker Inc. we współpracy z dostawcami oprogramowania.
- Zazwyczaj są bezpieczniejsze, dobrze udokumentowane i regularnie aktualizowane.
- Zazwyczaj nie mają prefiksu użytkownika w nazwie (np. po prostu nginx, a nie johnd/nginx).
- Obrazy od społeczności (Community Images / Publisher Images):
- Tworzone przez indywidualnych użytkowników lub firmy.
- Ich jakość i bezpieczeństwo mogą być różne.
- Zawsze mają prefiks nazwy użytkownika lub organizacji, która je opublikowała.
- Warto sprawdzać liczbę pobrań, gwiazdki, datę ostatniej aktualizacji oraz źródło (Dockerfile, jeżeli jest dostępny).
- Część z obrazów mogą być oznaczone etykietą „Verified Publisher” – obrazy tak oznaczone co prawda nie są oficjalnymi obrazami, ale twórcy są pozytywnie zweryfikowani jako Ci wytwarzający wysokiej jakości obrazy.
Zawsze, gdy to możliwe, polecam starać się używać oficjalnych obrazów lub zweryfikowanych twórców jako bazy lub gotowych rozwiązań. jeżeli musicie skorzystać z obrazu od społeczności, dokładnie go zweryfikujcie – w szczególności te, które nie są oznaczone żadną zaufaną etykietą.
Popularne obrazy i ich zastosowania
Docker Hub jest skarbnicą gotowych do użycia obrazów. Oto kilka przykładów popularnych obrazów i ich typowych zastosowań:
- nginx – Lekki i wydajny serwer WWW oraz reverse proxy. Świetny do serwowania statycznych stron, jako load balancer czy do cachowania.
- apache (httpd) – Inny popularny serwer WWW.
- mysql / postgres / mariadb – Popularne relacyjne bazy danych. Idealne do szybkiego postawienia bazy danych na potrzeby deweloperskie lub testowe.
- redis / memcached – Bazy danych typu klucz-wartość, często używane jako cache lub brokery wiadomości.
- mongodb – Popularna baza danych NoSQL (dokumentowa).
- python / node / openjdk / php / ruby – Oficjalne obrazy popularnych języków programowania i ich środowisk uruchomieniowych. Stanowią doskonałą bazę do budowania własnych obrazów aplikacji.
- wordpress / ghost – Gotowe obrazy popularnych systemów CMS.
- jenkins (jenkins/jenkins) / gitlab/gitlab-ce – Obrazy narzędzi CI/CD.
- ubuntu / alpine / centos – Obrazy popularnych dystrybucji Linuksa, często używane jako obrazy bazowe. alpine jest znany ze swojego minimalnego rozmiaru.
Limity Docker Hub
Warto wiedzieć, iż Docker Hub wprowadził pewne limity pobierania obrazów dla użytkowników anonimowych oraz tych z darmowymi kontami. Limity te dotyczą liczby pobrań (pull) obrazów z Docker Huba w określonym przedziale czasowym (np. na 6 godzin).
- Użytkownicy anonimowi – Mają niższy limit (np. 100 pobrań na 6 godzin na adres IP).
- Użytkownicy z darmowym kontem (zalogowani) – Mają wyższy limit (np. 200 pobrań na 6 godzin).
- Konta płatne (Pro, Team, Business) – Mają znacznie wyższe limity lub ich brak.
Wiele firm, zwłaszcza większych, decyduje się na utrzymywanie własnych, prywatnych repozytoriów obrazów Dockera. Rozwiązania takie jak Nexus Repository Manager, JFrog Artifactory czy usługi chmurowe (np. AWS ECR, GCP Artifact Registry, Azure Container Registry) pozwalają na hostowanie obrazów wewnątrz infrastruktury firmy. Działa to jak lokalny cache i jednocześnie centralne miejsce dla wszystkich obrazów używanych w organizacji, co nie tylko omija limity publicznego Docker Huba, ale także zwiększa bezpieczeństwo i kontrolę nad zależnościami. jeżeli pracujecie w firmie, która ma takie repozytorium, zwykle będziecie konfigurować swojego Dockera tak, aby najpierw szukał obrazów właśnie tam.
Praca z DockerHub
Mając konto na Docker Hub, możemy nie tylko pobierać obrazy, ale także publikować i zarządzać naszymi własnymi.
Jako przykład zbudujemy prosty server nginx dla naszej strony index.html.
<!-- index.html --> <!DOCTYPE html> <html> <head> <title>Moja strona w kontenerze</title> </head> <body> <h1>Witaj z Nginx w Dockerze!</h1> </body> </html> # Używamy oficjalnego obrazu Nginx jako bazowego FROM nginx:alpine # Kopiujemy własny plik index.html do katalogu, który Nginx obsługuje domyślnie COPY index.html /usr/share/nginx/html/index.htmlMając takie pliki w jednym folderze możemy sobie taki obraz zbudować: docker build -t my-image .

Tworzenie tagów
Zanim wyślemy obraz do Docker Huba, musimy go odpowiednio otagować. Tagowanie pozwala na wersjonowanie obrazów. Nazwa obrazu w Docker Hubie ma zwykle format nazwa_uzytkownika/nazwa_repozytorium:tag.
docker tag <id_obrazu_lub_stara_nazwa:stary_tag> <nazwa_uzytkownika_dockerhub>/<nazwa_repozytorium>:<nowy_tag>Zbudowaliśmy lokalnie obraz o my+image i chcemy go teray wysłać do naszego repozytorium my-private-image na swojego Docker Huba z tagiem v1.0.
Najpierw musimy otagować nasz lokalny obraz:
docker tag my-image uprogramisty/my-private-image:v1.0Po otagowaniu, nowy alias pojawi się na liście docker images. Jeden obraz może mieć wiele tagów. Powszechną praktyką jest tagowanie konkretnej wersji (np. v1.0, v1.1.2) oraz utrzymywanie tagu latest wskazującego na najnowszą stabilną wersję.

Warto tutaj zwrócić uwagę na drugą kolumnę. Teraz już nie mamy tagu latest jak wcześniej, tylko konkretną wersję jaką wskazaliśmy podczas wywoływania polecenia.
Publikacja na Docker Hub
Gdy nasz obraz jest już odpowiednio otagowany, możemy go wysłać (opublikować) na Docker Hub.
Na początek oczywiście musimy się zalogować do naszego konto z poziomu terminala użwając komendy docker login. Zostaniemy poproszeni o podanie nazwy użytkownika i hasła (lub tokenu dostępowego). jeżeli mamy lokalnie zainstalowanego docker desktop to powinno nas automatyczne zalogować.
Po pomyślnym zalogowaniu, używamy komendy docker push, aby wysłać obraz:
docker push <nazwa_uzytkownika_dockerhub>/<nazwa_repozytorium>:<tag>Kontynuując nasz przykład:
Docker prześle warstwy obrazu do Docker Huba. jeżeli repozytorium my-private-image nie istnieje na naszym koncie Docker Hub, zostanie ono automatycznie utworzone jako repozytorium publiczne (chyba iż mamy inne domyślne ustawienia na koncie).
Po zakończeniu push, nasz obraz będzie dostępny na Docker Hubie i inni (lub my sami na innych maszynach) będą mogli go pobrać dzięki docker pull uprogramisty/my-private-image:v1.0.

Aktualizacja obrazów
Aktualizacja obrazu w Docker Hubie sprowadza się do kilku kroków:
- Wprowadzamy zmiany w kodzie aplikacji lub w Dockerfile.
- Budujemy nową wersję lokalnie dzięki docker build, nadając mu nowy tag np. v1.1 lub używając tego samego tagu co wcześniej v1.0, jeżeli chcemy go nadpisać.
- Wykonujemy te same polecania co wcześniej do opublikowania obrazu.
Docker Hub automatycznie wykryje, które warstwy obrazu się zmieniły i prześle tylko te różnice, co optymalizuje proces wysyłania.

Usuwanie obrazów
Obrazy z Docker Huba (zarówno tagi, jak i całe repozytoria) usuwa się zwykle przez interfejs webowy Docker Huba. Po zalogowaniu się na swoje konto, możemy przejść do repozytorium, wybrać zakładkę „Tags” i usunąć konkretne tagi, lub w ustawieniach repozytorium usunąć całe repozytorium. W przypadku organizacji i płatnych kont mogą być dostępne opcje usuwania przez API, ale dla indywidualnego użytkownika interfejs webowy jest najprostszy.
Podsumowanie
I to by było na tyle, jeżeli chodzi o podstawy Dockera i Docker Huba! Mam nadzieję, iż ten przegląd najważniejszych komend, koncepcji tworzenia obrazów z Dockerfile i możliwości, jakie daje Docker Hub, okazał się dla Was przydatny. Docker to naprawdę game-changer, jeżeli chodzi o budowanie i wdrażanie aplikacji – ułatwia życie, zapewnia spójność środowisk i pozwala skupić się na tym, co najważniejsze, czyli na kodowaniu.
Pamiętajcie, iż najlepsza nauka to praktyka. Odpalajcie kontenery, twórzcie własne Dockerfile’e, eksperymentujcie z obrazami z Docker Huba. Im więcej będziecie używać tych narzędzi, tym szybciej staną się one dla Was naturalnym elementem codziennej pracy. jeżeli szukacie bardziej szczegółowych informacji, oficjalna dokumentacja Dockera (docs.docker.com) to zawsze najlepsze miejsce.
Mam nadzieję, iż ten wpis pomógł Ci lepiej zrozumieć, jak efektywnie pracować z Dockerem i Docker Hub. jeżeli masz pytania lub chcesz podzielić się swoimi doświadczeniami – śmiało, zostaw komentarz poniżej!