Czym jest Docker? Jak działa, jak zacząć i najczęstsze problemy

Mateusz Bogolubow

10-11-2026

Czym jest Docker, czym różni się kontener od maszyny wirtualnej i jak uruchomić swoją pierwszą aplikację? Przykłady z naszych testów oraz rozwiązania najczęstszych problemów.

Czym jest Docker? Jak działa, jak zacząć i najczęstsze problemy
Docker to narzędzie, które pakuje aplikację razem z jej zależnościami w obraz i uruchamia ją w odizolowanym kontenerze, dzięki czemu działa tak samo na każdym komputerze. Kontenery współdzielą jądro systemu, więc są lżejsze od maszyn wirtualnych, a dane w nich znikają razem z kontenerem, jeśli nie zapiszesz ich w wolumenie. Najczęstsze problemy to aplikacja niedostępna z zewnątrz (zły adres nasłuchu lub brak mapowania portu), utrata danych i localhost, który w kontenerze oznacza sam kontener.

„U mnie działa” to jedno z najstarszych zdań w programowaniu: kod działa na Twoim komputerze, a na serwerze lub u kolegi z zespołu nie. Docker powstał, żeby to ograniczyć, i dziś jest jednym z podstawowych narzędzi programisty. Poniżej wyjaśniamy, czym jest, czym różni się od maszyny wirtualnej i jak uruchomić pierwszą aplikację. Przykłady uruchomiliśmy na własnym komputerze, a w drugiej połowie artykułu pokazujemy najczęstsze problemy, które można w ten sposób odtworzyć, wraz z ich rozwiązaniami.

Czym jest Docker i do czego służy?

Docker to narzędzie do konteneryzacji (containerization): pakowania aplikacji razem ze wszystkim, czego potrzebuje do działania, czyli środowiskiem uruchomieniowym, bibliotekami i konfiguracją, w jedną jednostkę zwaną obrazem. Z tego obrazu uruchamiasz kontener, czyli odizolowany proces, który działa tak samo na laptopie, w zespole i na serwerze. Dlatego Docker służy przede wszystkim do:

  • ujednolicenia środowiska w zespole (każdy ma te same wersje narzędzi),
  • uruchamiania usług pomocniczych bez instalowania ich w systemie (baza danych, kolejka, cache),
  • wdrażania aplikacji na serwerze w przewidywalny sposób.

Warto też pamiętać, że Docker to jedna z implementacji kontenerów, a nie jedyna. Istnieją inne rozwiązania, np. Podman czy LXC, ale w praktyce o kontenerach mówi się dziś najczęściej „Docker”. Według Stack Overflow Developer Survey 2025 Docker używa 73,8% zawodowych programistów, więc to narzędzie, na które trafisz w większości zespołów.

Czym są obraz, kontener i Dockerfile?

Te pojęcia wracają na początku każdego kursu, a pierwsze trzy mylone są najczęściej:

PojęcieCo to jestAnalogia
Obraz (image)niezmienny „zapis” aplikacji i jej środowiskaprzepis lub szablon
Kontener (container)uruchomiona instancja obrazupotrawa ugotowana według przepisu
Dockerfileplik tekstowy z instrukcją budowy obrazuspis kroków przepisu
Rejestr (np. Docker Hub)miejsce, z którego pobierasz i gdzie wysyłasz obrazyksięgarnia przepisów
Wolumen (volume)miejsce na dane, które przeżywa usunięcie konteneralodówka poza kuchnią
Docker Composeplik opisujący kilka kontenerów, które działają razemmenu z kilku dań naraz

Z jednego obrazu możesz uruchomić dowolnie wiele kontenerów. Obrazów nie piszesz od zera, tylko budujesz je na gotowych: u nas bazą był node:22-alpine (235 MB), a dla porównania obraz hello-world ma 22,6 kB, alpine 26,6 MB, a redis:7-alpine 58,7 MB.

Czym różni się kontener od maszyny wirtualnej?

Maszyna wirtualna udaje cały komputer: ma własny system operacyjny razem z jądrem. Kontener nie ma własnego jądra, tylko współdzieli jądro systemu z komputerem, na którym działa, i izoluje jedynie procesy i pliki. Dlatego kontenery są mniejsze i startują szybciej niż maszyny wirtualne.

CechaMaszyna wirtualnaKontener
System operacyjnywłasny, razem z jądremwspółdzieli jądro hosta
Rozmiarzwykle gigabajtyod kilkudziesięciu kilobajtów do setek megabajtów (u nas 22,6 kB – 254 MB)
Izolacjapełnana poziomie procesów i plików
Typowe zastosowanieuruchamianie całych systemówuruchamianie pojedynczych aplikacji i usług

Ciekawostka z naszych testów: na komputerze Mac kontenery wciąż potrzebują Linuksa, bo to jego jądro współdzielą. Polecenie uname -sm uruchomione w kontenerze pokazało Linux aarch64, a na samym komputerze Darwin arm64:

docker run --rm alpine uname -sm
# Linux aarch64
uname -sm
# Darwin arm64

Na macOS i Windowsie Docker uruchamia więc w tle lekką maszynę wirtualną z Linuksem, a na samym Linuksie kontenery działają bezpośrednio. Różnice wirtualizacji i kontenerów dobrze tłumaczy w rozmowie senior DevOps Wojciech Lepczyński:

Jak zainstalować Dockera?

Najprostsza droga na Windowsie i macOS to Docker Desktop. Według dokumentacji na Windowsie potrzebuje 8 GB RAM, 64-bitowego procesora z SLAT i włączonej wirtualizacji sprzętowej w BIOS/UEFI oraz WSL 2 w wersji 2.1.5 lub nowszej, a na macOS co najmniej 4 GB RAM. Na Linuksie instalujesz Docker Engine z repozytorium swojej dystrybucji lub według dokumentacji Dockera. Wymagania sprzętowe Dockera i innych narzędzi zestawiamy w artykule Jaki komputer dla programisty, a o różnicach między systemami przy pracy z kontenerami (WSL 2, architektura procesora) piszemy w tekście System operacyjny dla programisty.

My testowaliśmy Docker Engine 29.9.3 w Colima (maszyna wirtualna z Linuksem uruchamiana z terminala) razem z oficjalnym klientem docker, a nie Docker Desktop. Polecenia i zachowanie silnika są te same, ale okna Docker Desktop i jego ustawień nie sprawdzaliśmy. Po instalacji sprawdź, czy wszystko działa:

docker --version
# Docker version 29.9.3, build 5457199aa5
docker run --rm hello-world
# Hello from Docker!
# This message shows that your installation appears to be working correctly.

Za pierwszym razem Docker pobiera obraz hello-world z rejestru (to widać w wyniku jako „Pulling from library/hello-world”), a kolejne uruchomienia korzystają z kopii zapisanej na dysku.

Jak uruchomić pierwszy kontener i jak nim zarządzać?

Podstawowy cykl pracy to uruchomienie, podgląd i zatrzymanie. Najważniejsze polecenia, które sprawdziliśmy:

PolecenieCo robi
docker run <obraz>pobiera obraz (jeśli go nie ma) i uruchamia z niego kontener
docker run -d --name <nazwa> -p 8080:3000 <obraz>uruchamia w tle, nadaje nazwę i mapuje port 8080 komputera na 3000 kontenera
docker pspokazuje działające kontenery (docker ps -a także zatrzymane)
docker logs <nazwa>pokazuje wyjście aplikacji, czyli pierwsze miejsce do szukania błędów
docker stop <nazwa>zatrzymuje kontener
docker rm <nazwa>usuwa kontener (opcja --rm robi to automatycznie po zatrzymaniu)
docker imagespokazuje obrazy pobrane na komputer

Jak napisać Dockerfile i zbudować własny obraz?

Zbudujmy obraz z prostej aplikacji w Node.js, która odpowiada na zapytania HTTP. Plik server.js:

const http = require("http");
const host = process.env.HOST || "0.0.0.0";
http.createServer((req, res) => {
  res.end("Cześć z kontenera! PID " + process.pid + "\n");
}).listen(3000, host, () => console.log("Nasłuchuję na " + host + ":3000"));

Oraz Dockerfile, czyli instrukcja budowy obrazu:

FROM node:22-alpine
WORKDIR /app
COPY package.json ./
RUN npm install --omit=dev
COPY server.js ./
CMD ["node", "server.js"]

Każda linia ma swoją rolę: FROM wskazuje obraz bazowy, WORKDIR ustawia katalog roboczy w obrazie, COPY kopiuje pliki z komputera, RUN wykonuje polecenie podczas budowania (tu instaluje zależności), a CMD mówi, co uruchomić, gdy powstaje kontener. Budujemy i uruchamiamy:

docker build -t demo:1 .
docker run -d --rm --name demo -p 8080:3000 demo:1
curl localhost:8080
# Cześć z kontenera! PID 1
docker ps --format '{{.Names}} | {{.Image}} | {{.Ports}}'
# demo | demo:1 | 0.0.0.0:8080->3000/tcp, [::]:8080->3000/tcp

Wynik obrazu demo:1 to 254 MB, z czego 235 MB to obraz bazowy. Zwróć uwagę na PID 1: aplikacja w kontenerze jest pierwszym i jedynym procesem, bo kontener nie startuje całego systemu.

Dlaczego kolejne budowanie obrazu trwa krócej?

Docker buduje obraz z warstw (layers), po jednej na instrukcję, i zapamiętuje je. Jeśli instrukcja i wszystko przed nią się nie zmieniły, używa zapamiętanej warstwy. U nas pierwsze budowanie zajęło 6,4 s (razem z instalacją pakietów), a po dopisaniu jednej linijki do server.js kolejne budowanie 0,47 s, bo warstwa z npm install wzięła się z pamięci podręcznej (w logu: „Using cache”). Dlatego w Dockerfile najpierw kopiuje się plik z zależnościami (package.json), instaluje je, i dopiero potem kopiuje resztę kodu: zmiana kodu nie wymusza wtedy ponownej instalacji pakietów.

Czym są wolumeny i dlaczego dane w kontenerze znikają?

Kontener domyślnie nie przechowuje danych na stałe. Zobacz, co się stało w naszym teście: zapisaliśmy plik w kontenerze, usunęliśmy kontener i uruchomiliśmy nowy:

docker run --name nov alpine sh -c 'echo dane > /data.txt; cat /data.txt'
# dane
docker rm nov
docker run --rm alpine cat /data.txt
# cat: can't open '/data.txt': No such file or directory

Plik zniknął razem z kontenerem. Rozwiązaniem jest wolumen (volume): miejsce zarządzane przez Dockera, które istnieje niezależnie od kontenera. Ten sam test z wolumenem:

docker volume create dane
docker run --rm -v dane:/data alpine sh -c 'echo dane > /data/plik.txt'
docker run --rm -v dane:/data alpine cat /data/plik.txt
# dane

Plik przetrwał, bo drugi, nowy kontener podłączył ten sam wolumen. Tak działa każda baza danych w kontenerze: katalog z danymi bazy montuje się jako wolumen, inaczej po usunięciu kontenera tracisz całą zawartość. To jeden z najpopularniejszych problemów: pytania o to, jak zachować dane bazy lub kolejki w kontenerze, mają na Stack Overflow dziesiątki tysięcy wyświetleń.

Czym jest Docker Compose i kiedy z niego korzystać?

Gdy aplikacja potrzebuje kilku usług naraz, np. serwera i bazy lub cache, nie uruchamiasz każdej ręcznie. Docker Compose pozwala opisać je w jednym pliku compose.yaml i wystartować jednym poleceniem. Poniżej minimalny przykład: Redis z wolumenem oraz drugi kontener, który sprawdza, czy widzi usługę Redis:

services:
  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data
  app:
    image: alpine
    depends_on:
      - redis
    command: sh -c "nc -zv redis 6379"
volumes:
  redis-data:
docker compose up
# app-1  | redis (172.18.0.2:6379) open
docker compose down -v

Dwie rzeczy warto zapamiętać. Po pierwsze, usługi w Compose widzą się po nazwie usługi (tu redis), a nie po adresie localhost. Po drugie, docker compose down zatrzymuje i usuwa kontenery oraz sieć, a dodane -v usuwa także wolumeny, więc użyj go świadomie. (W naszej instalacji polecenie nazywało się docker-compose, bo wtyczka Compose była zainstalowana osobno; w Docker Desktop działa jako docker compose.) Konteneryzację i Docker Compose ćwiczymy w praktyce w module Konteneryzacja: Docker.

Jakie są najczęstsze problemy z Dockerem i jak je rozwiązać?

Poniższe problemy odtworzyliśmy na własnym komputerze (macOS, Colima). Dla każdego podajemy objaw, przyczynę i rozwiązanie.

Naszym zdaniem warto wyrobić sobie jeden nawyk: przy każdym problemie zacznij od docker ps -a (czy kontener w ogóle działa i na jakich portach) oraz docker logs <nazwa> (co mówi aplikacja), a dopiero potem zgaduj przyczynę. W naszych testach log często od razu wskazywał winowajcę: komunikat „Nasłuchuję na 127.0.0.1:3000” wyjaśnił, dlaczego aplikacja jest niedostępna z zewnątrz, zanim zdążyliśmy zmieniać cokolwiek innego.

ObjawNajczęstsza przyczynaRozwiązanie
Strona z kontenera się nie otwiera, curl kończy się błędemaplikacja słucha na 127.0.0.1 w kontenerze albo brakuje -pnasłuchuj na 0.0.0.0 i mapuj port: -p 8080:3000
Kontener nie łączy się z inną usługą po localhostlocalhost w kontenerze to sam kontenerużyj nazwy usługi z Compose (np. redis)
Dane po usunięciu kontenera zniknęłybrak wolumenuzamontuj wolumen: -v dane:/data
curl odpowiada, ale inną aplikacją niż kontenerport na komputerze był już zajętysprawdź, co zajmuje port, i wybierz inny
exec format errorobraz zbudowany pod inną architekturę procesora--platform lub obraz wieloplatformowy
Brakuje miejsca na dyskuzbierają się stare obrazy i kontenerydocker system df, docker system prune

Dlaczego aplikacja w kontenerze jest niedostępna z zewnątrz?

Najczęstsza przyczyna to adres nasłuchu. Gdy ustawiliśmy HOST=127.0.0.1, aplikacja w kontenerze nasłuchiwała tylko wewnątrz niego, a curl z komputera zakończył się błędem z kodem 52 (pusta odpowiedź), mimo że port był zmapowany:

docker run -d --rm --name loc -e HOST=127.0.0.1 -p 8081:3000 demo:1
curl -s -m 5 localhost:8081
# curl exit 52
docker logs loc
# Nasłuchuję na 127.0.0.1:3000

Wskazówka była w logach, więc zaczynaj diagnozę od docker logs. Rozwiązanie: aplikacja w kontenerze ma nasłuchiwać na 0.0.0.0, a port musi być zmapowany przez -p. To odpowiedź na jedno z najczęstszych pytań o Dockera (pytania o przekierowanie portów w Compose mają na Stack Overflow kilkanaście tysięcy wyświetleń).

Co znaczy localhost w kontenerze?

Każdy kontener ma własną sieć, więc localhost oznacza w nim ten sam kontener, a nie Twój komputer ani inną usługę. W naszym teście nc -z localhost 6379 w kontenerze zakończyło się kodem 1 (brak połączenia), a to samo zapytanie do nazwy usługi redis w Compose działało. Gdy jedna usługa łączy się z drugą, używaj nazwy usługi z compose.yaml.

Dlaczego port jest zajęty, a Docker nic nie mówi?

U nas na komputerze port 3000 zajmowała lokalna aplikacja Next.js. Polecenie docker run -p 3000:3000 wystartowało bez błędu, a curl localhost:3000 odpowiedział stroną aplikacji z komputera, nie kontenerem. Tak zachowała się nasza konfiguracja (Colima na macOS); w Docker Desktop lub na Linuksie możesz zobaczyć komunikat o zajętym porcie, bo tego nie testowaliśmy. Wniosek jest ogólny: sprawdzaj odpowiedź, nie tylko to, że kontener się uruchomił. Co zajmuje port, sprawdzisz na macOS i Linuksie poleceniem:

lsof -nP -iTCP:3000 -sTCP:LISTEN

Co to jest „exec format error” i jak ją naprawić?

Kontenery współdzielą jądro hosta, więc obraz zbudowany dla procesorów amd64 nie uruchomi się na komputerze z procesorem arm64 (np. nowy Mac z procesorem Apple) bez emulacji. Typowy objaw to błąd exec format error (pytania o niego mają na Stack Overflow ponad 50 tys. wyświetleń). Rozwiązania: wybrać obraz dla swojej architektury, zbudować obraz wieloplatformowy albo wymusić emulację flagą --platform. U nas działało to tak:

docker run --rm --platform linux/amd64 alpine uname -m
# x86_64

Emulacja działa, ale według dokumentacji Dockera bywa „much slower than native”, więc to rozwiązanie awaryjne.

Co zrobić, gdy Docker zajmuje za dużo miejsca na dysku?

Obrazy, zatrzymane kontenery i wolumeny zbierają się z czasem. Zobacz, ile miejsca zajmują, i posprzątaj:

docker system df
# Images   6   0   326.2MB   60.07MB (18%)
docker system prune -f
# Total reclaimed space: 45.34kB

W naszym teście docker system prune nie usunął wolumenu (musieliśmy usunąć go ręcznie: docker volume rm dane), więc dane z wolumenów są bezpieczne przed zwykłym porządkowaniem. Uważaj jednak na opcje, które usuwają więcej, np. docker compose down -v, bo kasują wolumeny.

Czy znajomość Dockera pomaga w pracy?

Tak, bo Docker jest jednym z narzędzi, które pojawiają się w ofertach pracy i w codziennej pracy zespołów (Docker używa 73,8% zawodowych programistów w Stack Overflow Developer Survey 2025). Nie musisz znać go od pierwszego dnia nauki. Zacznij od uruchomienia gotowego obrazu, potem zbuduj własny z prostej aplikacji, a na końcu poznaj Compose.

Kiedy warto zacząć uczyć się Dockera?

Naszym zdaniem na początku nauki programowania nie musisz instalować Dockera: edytor, język i Git zajmą Ci wystarczająco dużo uwagi, a każde nowe narzędzie to kolejne źródło błędów. Sięgnij po niego wtedy, gdy projekt dostaje bazę danych lub inną usługę pomocniczą albo gdy chcesz, żeby cały zespół miał to samo środowisko. To moment, w którym Docker przestaje być dodatkową nauką, a zaczyna oszczędzać czas.

Masz pytanie do artykułu? Chcesz zgłosić błąd?

Pytaj ogólnie o temat artykułu albo napisz, co poprawić. Jeśli chcesz omówić swój konkretny przypadek, umów się na rozmowę. Ze względów bezpieczeństwa nie przeglądamy ani nie publikujemy żadnych linków. Wiadomości z linkami nie są zapisywane. Limit: 2 pytania na godzinę.

Wyślemy na niego link do potwierdzenia pytania i odpowiedź.

Ostateczną decyzję o opublikowaniu pytania podejmuje administrator.

Konsultacja i warsztaty devmentor.pl

Masz pytania?

Partnerzy

Firmy, z którymi współpracujemy

To partnerzy odpowiedzialni za staże po naszych kursach. Organizują je dla najlepszych absolwentów.

Zobacz wszystkich partnerów →
  • VR Medical
  • Sophona
  • Robot Force