Automatyzacja / DevOps30 marca 2025

Docker Poradnik 2025: Od Dockerfile do YAML – Krok po Kroku

Docker od podstaw: Dockerfile, docker-compose.yml, obrazy i kontenery. Budowanie aplikacji, wolumeny, sieci i deploy. Kompletny tutorial 2025.

#docker#dockerfile#docker-compose#kontenery#devops#obrazy docker#wolumeny#konteneryzacja
Docker - konteneryzacja aplikacji i docker-compose

Docker zrewolucjonizował sposób, w jaki tworzymy i wdrażamy aplikacje. Technologia konteneryzacji umożliwia tworzenie izolowanych środowisk zawierających wszystkie niezbędne zależności, eliminując problemy konfiguracyjne między środowiskami deweloperskimi a produkcyjnymi. Docker Compose pozwala zarządzać wieloma kontenerami za pomocą pojedynczego pliku YAML, upraszczając wdrażanie złożonych aplikacji.

W tym kompleksowym poradniku przeprowadzimy Cię przez wszystkie kluczowe aspekty Dockera – od podstawowych koncepcji i instalacji, przez tworzenie Dockerfile i zarządzanie obrazami, aż po konfigurację wielokontenerowych aplikacji za pomocą Docker Compose. Niezależnie od tego, czy dopiero zaczynasz przygodę z konteneryzacją, czy szukasz usystematyzowanej wiedzy, ten przewodnik pomoże Ci opanować Docker w praktyce.


Podstawy Dockera dla początkujących w 2025 roku

Czym jest Docker i dlaczego warto go używać?

Docker to platforma open-source umożliwiająca deweloperom pakowanie aplikacji wraz z ich zależnościami w standardowe jednostki zwane kontenerami. Kontenery zawierają kod aplikacji i całe środowisko potrzebne do działania – biblioteki, narzędzia systemowe oraz środowisko wykonawcze.

Kluczowe powody, dla których warto używać Dockera:

  • Spójność środowiska — eliminuje problem „u mnie działa", bo aplikacja działa identycznie w każdym środowisku
  • Szybkie wdrażanie — kontenery uruchamiają się w milisekundach, nie minutach
  • Izolacja aplikacji — każdy kontener działa niezależnie, bez wpływu na inne
  • Efektywne wykorzystanie zasobów — znacznie mniej zasobów niż tradycyjne maszyny wirtualne

Architektura Docker: kontenery vs maszyny wirtualne

Kontenery Docker współdzielą jądro systemu operacyjnego hosta, w przeciwieństwie do maszyn wirtualnych wymagających pełnego systemu operacyjnego gościa. Ta fundamentalna różnica architektoniczna ma kluczowe konsekwencje praktyczne.

Tradycyjne maszyny wirtualne:

  • Zawierają pełny system operacyjny gościa
  • Wymagają znacznie więcej zasobów (gigabajty RAM)
  • Czas uruchomienia liczony w minutach
  • Większa izolacja sprzętowa

Kontenery Docker:

  • Współdzielą jądro systemu operacyjnego hosta
  • Wymagają minimalnych zasobów (megabajty RAM)
  • Uruchamiają się w milisekundach
  • Izolacja na poziomie procesów

W praktyce oznacza to, że na jednym serwerze można uruchomić dziesiątki kontenerów, podczas gdy maszyny wirtualne ograniczyłyby tę liczbę do kilku instancji.

Kluczowe komponenty ekosystemu Docker w 2025

Ekosystem Docker składa się z kilku wzajemnie powiązanych komponentów:

  • Docker Engine — podstawowy komponent zawierający daemon (dockerd), REST API i klient CLI do zarządzania kontenerami
  • Docker Client — interfejs wiersza poleceń do komunikacji z daemonem Docker
  • Docker Desktop — aplikacja graficzna dla Mac, Windows i Linux dostarczająca wszystkie niezbędne narzędzia
  • Docker Objects — obrazy (szablony tylko do odczytu) i kontenery (uruchomione instancje obrazów)
  • Docker Registry — magazyn obrazów Docker (Docker Hub jako publiczny rejestr, lub prywatny rejestr firmowy)
  • Docker Compose — narzędzie do definiowania i uruchamiania aplikacji wielokontenerowych

Instalacja i konfiguracja środowiska Docker

Instalacja Docker na Windows, macOS i Linux

Windows:

  1. Pobierz Docker Desktop ze strony docker.com
  2. Uruchom plik instalacyjny .exe i postępuj zgodnie z instrukcjami
  3. Zaakceptuj umowę licencyjną
  4. Uruchom Docker Desktop z menu Start
  5. Włącz funkcję WSL 2 (Windows Subsystem for Linux)

Wymagania: Windows 10/11 Home lub Pro 22H2 (build 19045) lub nowszy.

macOS:

  1. Pobierz Docker Desktop (wersja dla Intel lub Apple Silicon)
  2. Przeciągnij ikonę Docker do folderu Aplikacje
  3. Uruchom Docker.app
  4. Zaakceptuj warunki umowy licencyjnej

Wymagania: macOS w jednej z trzech najnowszych wersji, minimum 4 GB RAM.

Linux (Ubuntu):

# Aktualizacja pakietów i instalacja wymaganych zależności
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common

# Dodanie klucza GPG repozytorium Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# Dodanie repozytorium Docker
sudo add-apt-repository "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Instalacja Docker Engine
sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io

# Uruchomienie i włączenie Docker przy starcie systemu
sudo systemctl start docker && sudo systemctl enable docker

Opcjonalnie, aby używać Dockera bez sudo:

sudo usermod -aG docker $USER
newgrp docker

Pierwsze uruchomienie i weryfikacja instalacji

Po zakończeniu instalacji warto zweryfikować, czy Docker działa prawidłowo:

# Sprawdzenie wersji Docker
docker --version

# Szczegółowe informacje o wersji
docker version

# Sprawdzenie statusu demona Docker (Linux)
sudo systemctl status docker

# Testowe uruchomienie kontenera
docker run hello-world

Polecenie docker run hello-world pobiera obraz testowy z Docker Hub, uruchamia kontener i wyświetla komunikat potwierdzający prawidłową instalację. Jeśli widzisz wiadomość „Hello from Docker!", Twoja instalacja działa poprawnie.

Konfiguracja Docker Desktop dla optymalnej wydajności

W ustawieniach Docker Desktop można dostroić kilka parametrów wpływających na wydajność:

Zasoby:

  • Limit CPU — dostosuj liczbę procesorów do potrzeb projektowych
  • Limit pamięci RAM — domyślnie 50% RAM hosta, można zmienić
  • Dysk wirtualny — określ maksymalny rozmiar dla obrazów i kontenerów

Tryb oszczędzania zasobów:

  • Włącz „Resource Saver" — automatycznie zmniejsza zużycie CPU i RAM, gdy brak uruchomionych kontenerów
  • Domyślny czas bezczynności przed aktywacją: 5 minut

Udostępnianie plików (macOS):

  • VirtioFS (dla macOS 12.5+) — najwyższa wydajność, zalecane
  • gRPC FUSE — alternatywa dla starszych wersji
  • osxfs (Legacy) — starsze wersje, niezalecane

Opcje VMM (macOS):

  • Docker VMM (Beta) — najnowszy, najwydajniejszy backend
  • Apple Virtualization framework — stabilna alternatywa
  • QEMU / HyperKit — starsze opcje

Tworzenie pierwszego Dockerfile krok po kroku

Struktura i składnia pliku Dockerfile

Dockerfile to plik tekstowy bez rozszerzenia, zawierający sekwencję instrukcji dla Docker Engine do budowania obrazu. Każda instrukcja tworzy nową warstwę w obrazie. Plik musi zaczynać się od instrukcji FROM, która określa obraz bazowy.

Podstawowa struktura:

# Komentarz opisujący cel
FROM obraz-bazowy:tag
INSTRUKCJA argumenty

Najważniejsze instrukcje Dockerfile

FROM — określa obraz bazowy, od którego zaczyna się budowanie:

FROM python:3.12-alpine

WORKDIR — ustawia katalog roboczy dla kolejnych instrukcji:

WORKDIR /app

COPY — kopiuje pliki i katalogi z hosta do systemu plików kontenera:

COPY . /app

RUN — wykonuje polecenia podczas budowania obrazu:

RUN pip install flask==3.0.*

ENV — ustawia zmienne środowiskowe:

ENV FLASK_APP=app.py

EXPOSE — informuje o portach, na których kontener nasłuchuje:

EXPOSE 5000

CMD — określa domyślne polecenie uruchamiane przy starcie kontenera:

CMD ["python", "app.py"]

Optymalizacja obrazów Docker z wykorzystaniem warstw

Obrazy Docker składają się z warstw. Tylko instrukcje RUN, COPY i ADD tworzą nowe warstwy w obrazie. Optymalizacja warstw bezpośrednio przekłada się na rozmiar obrazu i czas budowania.

Kluczowe wskazówki optymalizacji:

  1. Łącz polecenia RUN operatorem &&, aby zmniejszyć liczbę warstw:
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*
  1. Używaj lekkich obrazów bazowych — obrazy Alpine mają poniżej 6 MB, w porównaniu do setek megabajtów standardowych obrazów

  2. Stosuj budowanie wieloetapowe (multi-stage build) — użyj jednego obrazu do kompilacji, a drugiego, mniejszego, do uruchomienia:

# Etap budowania
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Etap produkcyjny
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/index.js"]
  1. Usuwaj niepotrzebne pliki w tej samej warstwie, w której zostały zainstalowane

Praktyczny przykład: Dockerfile dla aplikacji webowej

Poniżej kompletny Dockerfile dla aplikacji Flask:

# syntax=docker/dockerfile:1
FROM python:3.12-alpine

# Ustawienie katalogu roboczego
WORKDIR /app

# Kopiowanie i instalacja zależności (osobna warstwa dla cache)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Kopiowanie kodu aplikacji
COPY . .

# Ustawienie zmiennej środowiskowej
ENV FLASK_APP=app.py

# Informacja o porcie
EXPOSE 5000

# Komenda uruchamiająca aplikację
CMD ["flask", "run", "--host", "0.0.0.0", "--port", "5000"]

Budowanie i uruchamianie:

# Budowanie obrazu
docker build -t moja-aplikacja-flask .

# Uruchomienie kontenera
docker run -p 5000:5000 moja-aplikacja-flask

Zarządzanie obrazami i kontenerami Docker

Budowanie i tagowanie własnych obrazów

Budowanie obrazu z bieżącego katalogu:

docker build -t moja-nazwa-obrazu:v1.0 .

Struktura pełnej nazwy obrazu: [HOSTNAME[:PORT]/]ŚCIEŻKA[:TAG]

Przykłady tagowania:

# Dodanie dodatkowego tagu
docker image tag moj-obraz:v1.0 moj-obraz:latest

# Tagowanie dla Docker Hub
docker image tag moj-obraz:v1.0 uzytkownik/moj-obraz:v1.0

Uruchamianie, zatrzymywanie i usuwanie kontenerów

Podstawowe operacje na kontenerach:

# Uruchomienie kontenera w tle z mapowaniem portów
docker run -d -p 8080:80 --name moja-aplikacja nginx

# Wylistowanie uruchomionych kontenerów
docker ps

# Wylistowanie wszystkich kontenerów (także zatrzymanych)
docker ps -a

# Zatrzymanie kontenera
docker stop moja-aplikacja

# Uruchomienie zatrzymanego kontenera
docker start moja-aplikacja

# Usunięcie zatrzymanego kontenera
docker rm moja-aplikacja

# Wymuszenie usunięcia działającego kontenera
docker rm -f moja-aplikacja

Najczęściej używane flagi docker run:

  • -d — uruchamia kontener w tle (detached mode)
  • -p HOST:KONTENER — mapowanie portów (np. -p 8080:80)
  • --name — nadaje kontenerowi czytelną nazwę
  • -e — ustawia zmienną środowiskową
  • -v — montuje wolumin
  • --rm — automatycznie usuwa kontener po zatrzymaniu

Inspekcja i debugowanie działających kontenerów

Docker oferuje szereg narzędzi do diagnostyki:

# Lista wszystkich kontenerów ze statusem
docker ps -a

# Wyświetlenie logów kontenera
docker logs moja-aplikacja

# Śledzenie logów w czasie rzeczywistym
docker logs -f moja-aplikacja

# Szczegółowe informacje o kontenerze (JSON)
docker inspect moja-aplikacja

# Otwarcie interaktywnej powłoki w kontenerze
docker exec -it moja-aplikacja /bin/sh

# Debugowanie kontenera (Docker Desktop)
docker debug moja-aplikacja

Udostępnianie obrazów w Docker Hub

Aby udostępnić swój obraz innym:

# 1. Zaloguj się do Docker Hub
docker login

# 2. Zbuduj i otaguj obraz z nazwą użytkownika
docker build -t twoj-username/nazwa-obrazu:tag .

# 3. Wypchnij obraz do rejestru
docker push twoj-username/nazwa-obrazu:tag

Po wypchnięciu obraz jest dostępny publicznie (lub prywatnie, w zależności od ustawień) dla każdego, kto zna jego nazwę.


Docker Compose – konfiguracja wielokontenerowych aplikacji

Wprowadzenie do pliku compose.yaml

Docker Compose umożliwia zarządzanie aplikacjami złożonymi z wielu kontenerów za pomocą jednego pliku konfiguracyjnego compose.yaml (wcześniej docker-compose.yml). Zamiast uruchamiać każdy kontener osobno, definiujesz wszystkie usługi w jednym miejscu.

Prosty przykład:

services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"

Podstawowe polecenia Docker Compose:

# Uruchomienie wszystkich usług
docker compose up

# Uruchomienie w tle
docker compose up -d

# Zatrzymanie wszystkich usług
docker compose down

# Przebudowanie obrazów
docker compose up -d --build

Definiowanie usług, sieci i woluminów

Plik Compose pozwala definiować trzy główne elementy:

services:
  backend:
    image: moja-aplikacja:latest
    ports:
      - "8080:3000"
    networks:
      - app-network
    volumes:
      - dane-aplikacji:/data

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: mydb
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
    volumes:
      - dane-bazy:/var/lib/postgresql/data
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  dane-aplikacji:
  dane-bazy:

Domyślnie Docker Compose tworzy sieć, do której dołączają wszystkie kontenery. Każdy kontener jest dostępny dla innych pod nazwą usługi jako hostname (np. db zamiast adresu IP).

Zarządzanie zależnościami między kontenerami

Atrybut depends_on kontroluje kolejność uruchamiania usług. W połączeniu z condition i healthcheck zapewnia, że zależne usługi są w pełni gotowe:

services:
  web:
    build: .
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started

  db:
    image: postgres:15-alpine
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER}", "-d", "${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine

W tym przykładzie usługa web nie uruchomi się, dopóki baza danych db nie przejdzie pomyślnie testu zdrowia (healthcheck), a Redis nie zostanie uruchomiony.

Zmienne środowiskowe i sekrety w Docker Compose

Zmienne środowiskowe bezpośrednio w pliku:

services:
  web:
    environment:
      - DEBUG=true
      - API_URL=${API_ENDPOINT}

Zmienne z zewnętrznego pliku .env:

services:
  web:
    env_file:
      - path: ./common.env
      - path: ./override.env
        required: false

Sekrety dla danych wrażliwych (hasła, klucze API):

services:
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    file: ./db_password.txt

Sekrety są montowane jako pliki w kontenerze (w katalogu /run/secrets/), co jest bezpieczniejsze niż przekazywanie haseł przez zmienne środowiskowe.


Praktyczne zastosowania Docker w projektach programistycznych

Lokalne środowisko deweloperskie z Docker

Docker eliminuje problem „u mnie działa" dzięki zapewnieniu identycznego środowiska dla wszystkich członków zespołu. Nowi deweloperzy mogą rozpocząć pracę w ciągu kilku minut zamiast godzin konfiguracji.

Docker Desktop dostarcza funkcję „Dev Environments" umożliwiającą:

  • Tworzenie środowisk bezpośrednio z repozytoriów Git
  • Pracę w predefiniowanych środowiskach VS Code
  • Uruchamianie kodu w izolowanym kontenerze

Najlepsze praktyki dla środowiska deweloperskiego:

  • Zapisz konfigurację Docker w systemie kontroli wersji (Git)
  • Twórz pliki .env dla konfiguracji specyficznej dla środowiska
  • Montuj kod źródłowy jako woluminy — dzięki temu zmiany w kodzie są natychmiast widoczne bez przebudowy obrazu

Testowanie aplikacji w izolowanych kontenerach

Kontenery Docker to doskonałe środowiska testowe zapewniające izolację, powtarzalność i szybką konfigurację. Każdy test uruchamiany jest w czystym środowisku, bez wpływu poprzednich uruchomień.

Kluczowe zalety:

  • Powtarzalność — każdy test startuje z identycznego stanu
  • Równoległość — możliwość uruchamiania testów jednocześnie w oddzielnych kontenerach
  • Izolacja baz danych — każdy test może mieć własną instancję bazy danych
  • Szybkie czyszczenie — zatrzymanie kontenera usuwa wszystkie dane testowe

Narzędzia takie jak testcontainers integrują się z popularnymi frameworkami testowymi, automatycznie uruchamiając potrzebne usługi (bazy danych, kolejki wiadomości) na czas testów.

Integracja z narzędziami CI/CD

Docker stanowi fundament współczesnych potoków CI/CD, zapewniając spójne środowisko na wszystkich etapach — od budowania, przez testowanie, aż po wdrażanie.

Typowe zastosowania w pipeline CI/CD:

  • Uruchamianie zadań pipeline'u w izolowanych kontenerach
  • Budowanie obrazów Docker jako artefaktów wdrożeniowych
  • Automatyczne tagowanie i publikacja obrazów do rejestru
  • Wdrażanie na produkcję poprzez aktualizację obrazu kontenera

Popularne platformy CI/CD (GitHub Actions, GitLab CI, CircleCI, Jenkins) oferują gotowe integracje z Dockerem.

Mikrousługi i Docker: praktyczne podejście

Architektura mikrousługowa i Docker to naturalne połączenie. Każda mikrousługa jest pakowana jako niezależny kontener, co ułatwia rozwój, testowanie i wdrażanie poszczególnych komponentów.

Kluczowe zasady architektury mikrousługowej z Docker:

  • Osobny kontener dla każdej mikrousługi
  • Komunikacja przez dobrze zdefiniowane API (REST, gRPC)
  • Docker Compose do lokalnego rozwoju i testowania
  • Orkiestracja za pomocą Kubernetes lub Docker Swarm w środowisku produkcyjnym
  • Niezależne wdrażanie — każdą usługę można aktualizować oddzielnie

Wnioski

Docker zmienił paradygmat tworzenia, testowania i wdrażania aplikacji. Od eliminacji problemów ze środowiskami, przez przyspieszenie cyklu rozwoju, aż po wsparcie architektur mikrousługowych — konteneryzacja stała się standardem w nowoczesnym rozwoju oprogramowania.

Kluczowe wnioski z tego poradnika:

  • Kontenery vs VM — kontenery są lżejsze, szybsze i bardziej efektywne w wykorzystaniu zasobów
  • Dockerfile — właściwa optymalizacja warstw i budowanie wieloetapowe znacząco zmniejszają rozmiar obrazów
  • Docker Compose — umożliwia zarządzanie złożonymi aplikacjami wielokontenerowymi z jednego pliku
  • Praktyka — zacznij od prostych przypadków i stopniowo przechodź do zaawansowanych scenariuszy

Warto podkreślić, że Docker to nie tylko narzędzie deweloperskie — to fundament nowoczesnej infrastruktury IT, na którym budowane są systemy CI/CD, platformy chmurowe i architektura mikrousługowa.

Jeśli potrzebujesz pomocy we wdrożeniu Dockera i konteneryzacji w swoim projekcie, skontaktuj się z nami. W FoxLink Automation pomagamy firmom wdrażać nowoczesne rozwiązania DevOps — od konteneryzacji aplikacji, przez konfigurację CI/CD, aż po orkiestrację z Kubernetes.

Potrzebujesz pomocy IT?

Skontaktuj się z nami i dowiedz się, jak możemy pomóc Twojemu biznesowi

Napisz do nas