DevOps, Praca w IT

Docker – konteneryzacja aplikacji od podstaw

Docker

Jeśli pracujesz w IT dłużej niż rok, na pewno słyszałeś słowo Docker. Może w kontekście „u mnie działa”, może przy onboardingu do nowego projektu, a może po prostu dlatego, że znajomy devops wrzucił na LinkedIna post o kontenerach. Docker to dziś absolutny standard w branży – narzędzie, bez którego trudno wyobrazić sobie nowoczesny development, CI/CD czy deployment aplikacji.

W tym artykule tłumaczymy, czym jest Docker i konteneryzacja, jak działa, jak różni się od wirtualnych maszyn, jak zacząć pracę z Dockerem i co daje Docker Compose. Konkretnie, z przykładami.

Docker – co to właściwie jest?

Docker to platforma open-source do tworzenia, uruchamiania i zarządzania kontenerami. Projekt powstał w 2013 roku, a jego twórcy – firma dotCloud (później przemianowana na Docker Inc.) – zmienili sposób, w jaki programiści myślą o środowiskach uruchomieniowych.

Konteneryzacja to technologia, która pozwala pakować aplikację razem z jej wszystkimi zależnościami – bibliotekami, konfiguracją, środowiskiem – w jeden przenośny pakiet zwany kontenerem. Taki kontener działa identycznie na laptopie developera, na serwerze testowym i na produkcji. Koniec z klasycznym „u mnie działa”.

Zanim Docker trafił do mainstreamu, wdrażanie aplikacji było często nocnym koszmarem. Różne wersje bibliotek, zależności systemowe, różne konfiguracje środowisk – każdy krok w procesie deploymentu mógł skończyć się błędem. Docker rozwiązał ten problem raz na zawsze.

Konteneryzacja – jak to działa pod spodem?

Kontener to izolowany proces działający na tym samym jądrze systemu operacyjnego co host. Nie uruchamia osobnego systemu operacyjnego (jak maszyna wirtualna) – współdzieli kernel hosta, ale ma własną warstwę systemu plików, własne zmienne środowiskowe i własne zasoby sieciowe.

Docker korzysta z dwóch kluczowych mechanizmów Linuksa:

  • namespaces – izolują procesy, sieć, system plików i użytkowników w obrębie kontenera,
  • cgroups (control groups) – kontrolują i limitują zasoby CPU, pamięci RAM i I/O przydzielone kontenerowi.

To właśnie te mechanizmy sprawiają, że kontenery są lekkie i szybkie – uruchamiają się w sekundy, nie minuty.

Docker vs VM – główne różnice

To jedno z najczęściej zadawanych pytań przez osoby zaczynające przygodę z konteneryzacją. Docker vs VM to nie wybór lepszego narzędzia – to dwie różne technologie do różnych zadań. Ale warto wiedzieć, czym się różnią.

Maszyna wirtualna (VM) emuluje pełny komputer – ma własny system operacyjny, własne sterowniki, własny kernel. Hypervisor (np. VMware, VirtualBox, Hyper-V) zarządza VM-kami i alokuje zasoby sprzętowe. To daje pełną izolację, ale kosztem rozmiaru (obrazy VM to często dziesiątki GB) i czasu startu (minuty).

Docker nie emuluje systemu operacyjnego. Kontener startuje w ciągu sekund, a jego obraz waży zazwyczaj kilkadziesiąt MB. Dzięki temu na jednym hoście możesz bez problemu uruchomić dziesiątki kontenerów z zasobami.

Porównanie Docker vs VM

CechaDocker (kontener)VM (maszyna wirtualna)
System operacyjnyWspółdzielony kernel hostaWłasny, pełny OS
Czas startuSekundyMinuty
Rozmiar obrazuMB (10–500 MB)GB (5–30 GB)
IzolacjaProcesowa (namespace)Pełna (hypervisor)
WydajnośćZbliżona do natywnejNarzut hypervisora
PrzenośnośćBardzo wysokaOgraniczona
ZastosowanieMikroserwisy, dev, CI/CDPełna izolacja OS, legacy apps

Praktyczna zasada: jeśli potrzebujesz uruchomić wiele serwisów aplikacyjnych w izolacji, Docker jest lepszym wyborem. Jeśli musisz emulować inny system operacyjny lub masz wymagania bezpieczeństwa wymagające pełnej izolacji sprzętowej – VM jest odpowiednim narzędziem. W wielu środowiskach produkcyjnych obie technologie działają razem.

Docker tutorial – jak zacząć?

Przejdźmy do praktyki. Poniżej znajdziesz wszystko, czego potrzebujesz, żeby zacząć pracę z Dockerem – od instalacji po pierwsze uruchomienie kontenera.

Instalacja Dockera

Docker Desktop to najprostszy sposób na start – instalator dostępny na Windows, macOS i Linux. Po instalacji dostajesz CLI, GUI i wszystkie niezbędne komponenty. Pobierz ze strony docker.com.

Na serwerze z Ubuntu instalacja wygląda tak:

sudo apt update
sudo apt install docker.io
sudo systemctl enable --now docker
docker --version  # sprawdź wersję

Kluczowe pojęcia Dockera

Image (obraz) – szablon kontenera. Read-only. Zawiera system plików, kod aplikacji, zależności. Pobierasz je z Docker Hub lub budujesz samodzielnie za pomocą Dockerfile.

Container (kontener) – uruchomiona instancja obrazu. Możesz uruchomić wiele kontenerów z jednego obrazu jednocześnie.

Dockerfile – plik tekstowy z instrukcjami budowania obrazu. Definiujesz w nim bazowy obraz, kopiujesz pliki, instalujesz zależności, ustawiasz zmienne środowiskowe.

Docker Hub – publiczne repozytorium obrazów. Znajdziesz tam gotowe obrazy nginx, postgres, node, python, redis i tysiące innych.

Volume – mechanizm trwałego przechowywania danych. Dane w kontenerze są ulotne – volume pozwala je utrwalić.

Network – wirtualna sieć łącząca kontenery. Domyślnie kontenery są izolowane sieciowo – musisz je połączyć, żeby mogły się komunikować.

Pierwsze kroki – uruchamiamy kontener

Zacznijmy od klasycznego „Hello World”:

docker run hello-world

Docker pobierze obraz hello-world z Docker Hub (jeśli nie masz go lokalnie) i uruchomi kontener, który wypisze krótki komunikat. To wszystko.

docker run -d -p 8080:80 --name moj-nginx nginx

Flagi: -d uruchamia w tle (detached), -p 8080:80 mapuje port 8080 hosta na port 80 kontenera, –name nadaje kontenerowi nazwę. Po uruchomieniu otwórz http://localhost:8080 w przeglądarce – zobaczysz stronę powitalną nginx.

Kilka przydatnych komend:

docker ps                    # lista działających kontenerów
docker ps -a                 # wszystkie kontenery (też zatrzymane)
docker stop moj-nginx        # zatrzymaj kontener
docker start moj-nginx       # uruchom ponownie
docker rm moj-nginx          # usuń kontener
docker images                # lista lokalnych obrazów
docker rmi nginx             # usuń obraz
docker logs moj-nginx        # pokaż logi kontenera
docker exec -it moj-nginx sh # wejdź do kontenera (shell)

Dockerfile – budujemy własny obraz

Gotowe obrazy z Docker Hub to dobry punkt startowy, ale w prawdziwych projektach budujesz własne obrazy ze swoją aplikacją. Do tego służy Dockerfile.

Przykładowy Dockerfile dla aplikacji Node.js:

# Bazowy obraz
FROM node:20-alpine


# Katalog roboczy w kontenerze
WORKDIR /app


# Kopiuj pliki package.json i zainstaluj zależności
COPY package*.json ./
RUN npm install --production


# Kopiuj resztę kodu aplikacji
COPY . .


# Eksponuj port
EXPOSE 3000


# Komenda startowa
CMD ["node", "server.js"]

Budowanie obrazu i uruchamianie:

docker build -t moja-aplikacja:1.0 .
docker run -d -p 3000:3000 moja-aplikacja:1.0

Kilka dobrych praktyk przy pisaniu Dockerfile: używaj lekkich obrazów bazowych (alpine zamiast ubuntu), łącz komendy RUN w jeden krok (mniej warstw = mniejszy obraz), kopiuj tylko niezbędne pliki i używaj .dockerignore (analogia do .gitignore) żeby nie pakować node_modules czy .env do obrazu.

Docker Compose – zarządzanie wieloma kontenerami

Pojedynczy kontener to prosty case. Prawdziwe aplikacje składają się z wielu serwisów – frontend, backend, baza danych, cache, kolejka. Docker Compose to narzędzie pozwalające definiować i uruchamiać aplikacje wielokontenerowe za pomocą jednego pliku YAML.

Zamiast uruchamiać każdy kontener ręcznie osobną komendą docker run, definiujesz wszystkie serwisy w pliku docker-compose.yml i uruchamiasz całość jedną komendą.

Przykładowy docker-compose.yml

Klasyczny stack webowy: aplikacja Node.js + baza PostgreSQL + Redis jako cache:

version: '3.9'


services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      - db
      - redis


  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data


  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data


volumes:
  postgres_data:
  redis_data:

Uruchomienie całego stacku:

docker compose up -d          # uruchom w tle
docker compose ps             # status serwisów
docker compose logs -f app    # logi aplikacji na żywo
docker compose down           # zatrzymaj i usuń kontenery
docker compose down -v        # też usuń volumes

Co zyskujesz dzięki Docker Compose?

  • Jedno polecenie uruchamia cały stack aplikacyjny – idealnie na onboarding nowych developerów.
  • Konfiguracja środowiska jest w repozytorium – każdy ma identyczne środowisko lokalne.
  • Izolacja między projektami – każdy projekt ma swoje sieci i volumes.
  • Łatwe skalowanie – docker compose up –scale app=3 uruchamia 3 instancje serwisu app.
  • Override pliki – docker-compose.override.yml dla środowiska dev, osobny plik dla produkcji.

Docker w polskiej branży IT – czy to nadal wymaganie?

Tak – i to mocne. Docker pojawia się w ogłoszeniach rekrutacyjnych na praktycznie każdą rolę backendową, fullstackową i devopsową. W 2024 roku Stack Overflow Developer Survey wykazało, że Docker jest najczęściej używanym narzędziem w kategorii narzędzi developerskich wśród profesjonalnych programistów – korzysta z niego 59% respondentów. Co więcej, Docker zajął jednocześnie pierwsze miejsce jako narzędzie najbardziej pożądane i najbardziej podziwiane (78%).

Na polskim rynku IT znajomość Dockera to dziś standard porównywalny ze znajomością Git. Brak tej umiejętności u mid/senior developera budzi zdziwienie rekruterów technicznych. Co więcej, Docker jest podstawą pod Kubernetes – a znajomość k8s jest jedną z najlepiej wycenianych kompetencji w branży.

Rola, w której Docker pojawia się najczęściej jako wymagane lub mile widziane narzędzie, to:

  • Backend Developer (Node.js, Python, Java, .NET) – praca z kontenerami przy lokalnym devie i CI/CD,
  • DevOps / Platform Engineer – zarządzanie kontenerami, Kubernetes, infrastruktura,
  • Fullstack Developer – lokalny stack wielokontenerowy,
  • QA / Test Automation Engineer – izolowane środowiska testowe w kontenerach,
  • Data Engineer / MLOps – pakowanie pipeline’ów ML w kontenery.

Dobre praktyki pracy z Dockerem

Znajomość komend docker run to dopiero początek. Żeby efektywnie pracować z Dockerem w projekcie produkcyjnym, warto znać kilka zasad.

Bezpieczeństwo

  • Nie uruchamiaj kontenerów jako root – używaj dyrektywy USER w Dockerfile.
  • Skanuj obrazy pod kątem podatności – narzędzia: Trivy, Snyk, docker scout.
  • Nie przechowuj sekretów w obrazach ani zmiennych środowiskowych w docker-compose.yml – używaj Docker Secrets lub zewnętrznych vaultów.
  • Używaj obrazów z oficjalnych repozytoriów lub takich, które sam/a budujesz.
  • Regularnie aktualizuj obrazy bazowe – stare wersje mają znane CVE.

Optymalizacja obrazów

  • Używaj multi-stage builds – buduj aplikację w jednym etapie, kopiuj tylko artefakty do finalnego obrazu.
  • Wybieraj alpine lub distroless jako obraz bazowy – mniejszy rozmiar, mniejsza powierzchnia ataku.
  • Każda warstwa obrazu to cache – układaj instrukcje od najmniej do najbardziej zmieniających się.
  • Używaj .dockerignore – wyklucz node_modules, .git, pliki lokalne.

Przykład multi-stage build dla aplikacji Go – obraz finalny waży kilka MB:

# Etap budowania
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp .


# Obraz finalny
FROM alpine:3.19
COPY --from=builder /app/myapp /usr/local/bin/
CMD ["myapp"]

Logi i monitoring

  • Pisz logi na stdout/stderr – Docker automatycznie je zbierze.
  • Ustaw limity zasobów – memory i CPU limits w docker-compose.yml zapobiegną zagłodzeniu hosta.
  • Używaj health checks – Docker Compose i Kubernetes korzystają z healthchecka do zarządzania serwisem.

Co po Dockerze? Kierunki rozwoju

Kiedy opanujesz Dockera, naturalnym krokiem jest Kubernetes (k8s) – system orkiestracji kontenerów. Kubernetes zarządza dziesiątkami, setkami lub tysiącami kontenerów w klastrze serwerów, zapewniając automatyczne skalowanie, self-healing i rolling deployments. To kompetencja, która znacząco podnosi wycenę na rynku pracy.

Warto też zainteresować się:

  • Docker Swarm – prostszy alternatywny orkiestrator, wbudowany w Docker Engine,
  • Podman – alternatywa dla Dockera bez daemona, popularna w środowiskach enterprise (Red Hat),
  • BuildKit – nowy silnik budowania obrazów z obsługą cache i buildx dla multi-platform,
  • GitHub Actions / GitLab CI – pipeline CI/CD z kontenerami Docker jako środowisko budowania i testowania,
  • Amazon ECS, Google Cloud Run, Azure Container Instances – managed container services w chmurze.

Podsumowanie

Docker to narzędzie, które zrewolucjonizowało sposób budowania i wdrażania aplikacji. Konteneryzacja rozwiązała jeden z największych bólów głowy developerów – różnice między środowiskami. Dziś Docker jest standardem branżowym, a jego znajomość to inwestycja, która zwraca się szybko.

Kilka najważniejszych wniosków:

  • Docker pakuje aplikację z wszystkimi zależnościami – działa identycznie wszędzie,
  • Kontenery są lżejsze i szybsze niż VM – współdzielą kernel hosta,
  • Dockerfile to przepis na obraz – powtarzalny, wersjonowany, przenośny,
  • Docker Compose upraszcza pracę z wieloma serwisami – jedno polecenie, cały stack,
  • Na polskim rynku IT Docker to wymagana umiejętność dla większości ról backendowych i DevOps.

Jeśli dopiero zaczynasz – zainstaluj Docker Desktop, przerób oficjalny „Get Started” tutorial na docs.docker.com i spróbuj skonteneryzować własny projekt. Kilka godzin praktyki zastąpi dni czytania teorii.

Redaktorka, dziennikarka i copywriterka, autorka wywiadów, tekstów eksperckich, newsów poświęconych branży IT (i nie tylko).

Podobne artykuły