Pytanie o to, jak korzystać z dockera w projekcie, pojawia się zwykle wtedy, gdy aplikacja działa bez zarzutu na laptopie jednego programisty, a na serwerze testowym wysypuje się przy pierwszym uruchomieniu. Odpowiedź na pytanie, jak korzystać z dockera w projekcie, sprowadza się do trzech elementów: opisania środowiska w pliku Dockerfile, spięcia usług w docker compose i zbudowania obrazu, który zachowuje się identycznie na stacji roboczej, w systemie CI oraz na produkcji. Kontener nie jest maszyną wirtualną — to izolowany proces korzystający z jądra hosta, dlatego uruchamia się w ułamku sekundy, a narzut pamięci liczy się w megabajtach, nie gigabajtach. Dzięki temu piętnastoosobowy zespół pracuje na tej samej wersji PostgreSQL, Redisa i Node.js bez ręcznej instalacji czegokolwiek poza samym silnikiem kontenerów. Poniżej znajdziesz polecenia, liczby i schematy wdrożenia sprawdzone w projektach komercyjnych.
Silnik, obraz i kontener — fundament, od którego zaczynasz
Docker Engine to demon działający w tle systemu. Na dystrybucjach Linuksa instaluje się natywnie w dwie minuty, na Windowsie i macOS korzysta z warstwy pośredniej — odpowiednio WSL2 oraz lekkiej maszyny wirtualnej. Docker Desktop pozostaje bezpłatny dla małych firm i projektów niekomercyjnych, a licencja korporacyjna to wydatek rzędu kilkudziesięciu złotych miesięcznie na użytkownika.
Obraz i kontener to dwie różne rzeczy, a mylenie ich generuje większość błędów początkujących. Obraz jest niezmiennym szablonem złożonym z warstw systemu plików. Kontener to uruchomiona instancja obrazu z dodatkową, zapisywalną warstwą, która znika po usunięciu procesu. Polecenie docker run -d –name api -p 8080:8080 myapp:1.4 tworzy taką instancję i mapuje port hosta.
Obrazy przechowuje rejestr: publiczny Docker Hub, GitHub Container Registry albo prywatne repozytorium w chmurze operatora. Prywatny rejestr w podstawowym planie kosztuje kilkanaście do kilkudziesięciu złotych miesięcznie i zwykle limituje transfer. Tagowanie semantyczne w formacie 1.4.2 zamiast wszechobecnego latest pozwala cofnąć wdrożenie jednym poleceniem, bez zgadywania, co faktycznie działa na serwerze.
Dockerfile, który nie przeterminuje się po miesiącu
Kolejność instrukcji decyduje o skuteczności cache. Najpierw FROM node:22-alpine, potem WORKDIR /app, następnie COPY package.json package-lock.json oraz RUN npm ci, a dopiero na końcu COPY reszty kodu. Przy takim układzie zmiana jednego pliku źródłowego nie unieważnia warstwy z zależnościami, więc rebuild trwa sekundy zamiast kilku minut.
Plik .dockerignore powinien wykluczać node_modules, katalog .git, logi i pliki środowiskowe — bez niego kontekst budowania potrafi urosnąć do kilkuset megabajtów. Dodaj też instrukcję USER z kontem nieuprzywilejowanym oraz HEALTHCHECK odpytujący endpoint zdrowia. Orkiestrator dzięki temu wie, czy proces faktycznie odpowiada, a nie tylko czy istnieje.
Docker compose, czyli jak korzystać z dockera w projekcie wielousługowym
Pojedynczy kontener rzadko wystarcza. Plik compose.yaml opisuje komplet usług: aplikację, bazę danych, Redisa i reverse proxy. Jedno polecenie docker compose up -d podnosi całe środowisko, a docker compose down -v czyści je razem z wolumenami. Nowy programista uruchamia projekt w kwadrans zamiast spędzać dzień na konfiguracji lokalnej maszyny.
Usługi w jednym pliku compose trafiają do wspólnej sieci mostkowej i widzą się po nazwach. Aplikacja łączy się z bazą przez host db, nie przez adres IP. Parametr depends_on z warunkiem service_healthy wstrzymuje start API do momentu, aż PostgreSQL faktycznie przyjmie połączenie — to eliminuje klasyczny wyścig przy starcie stosu.
Konfigurację trzymaj w zmiennych środowiskowych ładowanych z pliku .env, który nigdy nie trafia do repozytorium. Hasła produkcyjne przekazuj mechanizmem secrets albo menedżerem sekretów operatora chmury. Osobny plik compose.override.yaml pozwala trzymać ustawienia deweloperskie, takie jak montowanie kodu na żywo, z dala od konfiguracji produkcyjnej.
Lekkie obrazy i budowanie wieloetapowe
Obraz o rozmiarze 1,2 GB kosztuje realny czas przy każdym wdrożeniu i każdym uruchomieniu potoku CI. Budowanie wieloetapowe rozwiązuje problem elegancko: pierwszy etap kompiluje kod z pełnym zestawem narzędzi, drugi kopiuje wyłącznie gotowe artefakty do minimalnego obrazu bazowego. Redukcja o osiemdziesiąt do dziewięćdziesięciu procent to typowy rezultat.
| Obraz bazowy | Przybliżony rozmiar | Zastosowanie |
|---|---|---|
| node:22 | 1,1 GB | etap kompilacji |
| node:22-slim | 250 MB | uniwersalna produkcja |
| node:22-alpine | 140 MB | mikrousługi, API |
| distroless | 110 MB | środowiska o wysokich wymogach bezpieczeństwa |
| scratch | 12 MB | statyczne binaria Go i Rust |
Alpine korzysta z biblioteki musl zamiast glibc, co potrafi popsuć pakiety kompilowane natywnie, na przykład sterowniki bazodanowe czy biblioteki graficzne. Jeżeli testy przechodzą, zysk jest wyraźny. Jeśli pojawiają się dziwne błędy segmentacji, wariant slim stanowi bezpieczny kompromis między rozmiarem a zgodnością z ekosystemem pakietów.
Dane trzymaj poza kontenerem. Wolumen nazwany podpięty do katalogu bazy danych przetrwa aktualizację obrazu, przebudowę i restart hosta. Katalog z plikami użytkowników montuj jako bind mount lub kieruj do obiektowego magazynu S3. Kontener ma być jednorazowy — jego usunięcie nie może oznaczać utraty jakichkolwiek danych produkcyjnych.
Wdrożenie kontenerów na serwerze i migracja z klasycznego hostingu
Kontenery trzeba gdzieś uruchomić, a tu pojawia się pytanie, czym różni się VPS od hostingu współdzielonego. Odpowiedź jest jednoznaczna: na koncie współdzielonym nie masz uprawnień roota ani dostępu do jądra, więc silnik kontenerów po prostu nie wystartuje. Minimum to VPS z dwoma rdzeniami i czterema gigabajtami RAM, od około pięćdziesięciu złotych miesięcznie.

Decyzja, jak wybrać hosting pod WordPress, wygląda zupełnie inaczej niż dobór maszyny pod kontenery. Klasycznemu CMS-owi wystarczy PHP-FPM, MySQL i panel administracyjny za dwadzieścia złotych miesięcznie. Aplikacja kontenerowa potrzebuje własnego serwera z pełną kontrolą, systemd, otwartym portem 2375 tylko lokalnie i regularnymi aktualizacjami jądra.
Procedura tego, jak przenieść stronę na inny hosting, przy migracji do kontenerów obejmuje cztery kroki: zrzut bazy poleceniem mysqldump, kopię katalogu z plikami, zbudowanie obrazu z tą samą wersją PHP i wreszcie przełączenie delegacji. Stare adresy obsłuż przekierowaniami — jak ustawić przekierowanie 301 w htaccess dotyczy Apache, w Nginksie odpowiada temu dyrektywa return 301.
Domena, rekordy DNS i certyfikat dla aplikacji w kontenerze
Zanim wskażesz domenę na nowy adres, sprawdź stan rejestracji. Kwestia tego, jak sprawdzić kto jest właścicielem domeny, rozwiązuje się przez zapytanie WHOIS lub RDAP w rejestrze krajowym. Temat, jak przedłużyć domenę po wygaśnięciu, bywa kosztowny: po okresie karencji wchodzi faza odzyskiwania z opłatą sięgającą kilkuset złotych.
Kolejny etap to jak skonfigurować rekordy DNS domeny pod kontenerowe wdrożenie. Rekord A kieruje domenę główną na adres IPv4 serwera, rekord AAAA na IPv6. Warto wiedzieć, co to jest rekord CNAME — to alias wskazujący jedną nazwę na drugą, przydatny dla subdomen typu api czy panel obsługiwanych przez ten sam reverse proxy.
Zagadnienie, jak zainstalować certyfikat SSL na serwerze, w świecie kontenerów rozwiązują Traefik i Caddy. Oba pobierają i odnawiają darmowy certyfikat SSL Let’s Encrypt automatycznie, na podstawie etykiet w pliku compose. Certyfikat ma ważność dziewięćdziesięciu dni, a odnowienie startuje trzydzieści dni przed końcem, bez ingerencji administratora.
Monitoring, wydajność sieci i codzienne utrzymanie
Podstawowa diagnostyka to docker logs -f nazwa oraz docker stats pokazujące zużycie procesora, pamięci i transferu w czasie rzeczywistym. Poważniejsze wdrożenia dokładają cAdvisor zbierający metryki kontenerów, Prometheusa jako bazę szeregów czasowych i Grafanę do wykresów. Polityka restart: unless-stopped podnosi usługę po awarii i po restarcie hosta.
Gdy aplikacja zwalnia, sprawdź łącze, zanim zaczniesz obwiniać obrazy. Rzetelna odpowiedź na to, jak sprawdzić prędkość internetu rzetelnie, to test iperf3 między serwerem a stacją roboczą, powtórzony kilkukrotnie w godzinach szczytu i po kablu, nie po radiu. Przeglądarkowe testy mierzą trasę do losowego węzła, nie do twojego VPS-a.
W biurze domowym problemem bywa łącze bezprzewodowe. Pytanie, jak wzmocnić sygnał WiFi w domu, sprowadza się do trzech działań: przeniesienia routera na środek mieszkania, wymuszenia pasma 5 GHz dla stacji roboczej oraz zmiany kanału na najmniej obciążony. System mesh z dwoma punktami dostępowymi to koszt od czterystu złotych.
Higiena środowiska zamyka temat tego, jak korzystać z dockera w projekcie utrzymywanym przez lata. Cotygodniowe docker system prune -af –volumes odzyskuje dziesiątki gigabajtów, skanowanie obrazów narzędziem trivy lub docker scout wykrywa podatności w warstwach bazowych, a comiesięczna aktualizacja obrazów bazowych zamyka luki, o których nikt nie przeczyta w changelogu.
Jak zacząć korzystać z Dockera w projekcie, który już działa na produkcji?
Nie przepisuj wszystkiego naraz. Zacznij od konteneryzacji środowiska deweloperskiego: przygotuj compose.yaml z bazą danych i cache, żeby zespół przestał instalować je lokalnie. Ten krok nie dotyka produkcji, a już eliminuje większość zgłoszeń o działaniu tylko na jednej maszynie. Następnie zbuduj obraz samej aplikacji i uruchom na nim testy w potoku CI — to weryfikuje poprawność Dockerfile bez ryzyka. Trzeci etap to wdrożenie kontenera na środowisko staging z identyczną konfiguracją jak produkcja. Dopiero czwarty krok obejmuje przełączenie ruchu produkcyjnego, najlepiej metodą blue-green, z zachowaną możliwością natychmiastowego powrotu do poprzedniej wersji. Cała migracja średniej wielkości aplikacji zajmuje zwykle od dwóch do sześciu tygodni pracy jednej osoby.
Czy Docker spowalnia aplikację w porównaniu z instalacją natywną?
Na Linuksie narzut jest praktycznie niemierzalny, ponieważ kontener to zwykły proces izolowany mechanizmami namespaces i cgroups, korzystający bezpośrednio z jądra hosta. Testy obciążeniowe pokazują różnice rzędu jednego do trzech procent w obliczeniach procesora i podobnie w przepustowości sieci przy sieci host. Wyjątkiem są operacje dyskowe realizowane przez sterownik overlay2 na warstwie zapisywalnej — tam spadek bywa zauważalny, dlatego bazy danych zawsze montuje się na wolumenach, które omijają tę warstwę. Na Windowsie i macOS sytuacja wygląda gorzej, bo kontenery działają wewnątrz maszyny wirtualnej, a operacje na plikach montowanych z hosta potrafią być kilkukrotnie wolniejsze. Rozwiązaniem jest trzymanie kodu w wolumenie nazwanym albo praca w kontenerze deweloperskim.
Co zrobić, gdy kontenery zajmują zbyt dużo miejsca na dysku?
Najpierw zdiagnozuj problem poleceniem docker system df, które rozbija zużycie na obrazy, kontenery, wolumeny i cache budowania. W typowym środowisku deweloperskim po kilku miesiącach pracy największym winowajcą jest cache buildera, potrafiący urosnąć do kilkudziesięciu gigabajtów. Polecenie docker builder prune -af czyści go w całości. Nieużywane obrazy usuwa docker image prune -a, a osierocone wolumeny docker volume prune — to ostatnie wykonuj świadomie, bo wolumen może przechowywać jedyną kopię lokalnej bazy. Zapobiegawczo ustaw w pliku daemon.json rotację logów sterownikiem json-file z parametrami max-size na dziesięć megabajtów i max-file na trzy, bo niekontrolowane logi kontenerów są drugą najczęstszą przyczyną zapełnienia partycji.

