Pytania rekrutacyjne Docker

42 pytań — 20 odpowiedzi dostępnych od razu

Pytania rekrutacyjne Docker często sprawdzają, czy rozumiesz różnicę między obrazem, kontenerem i wolumenem oraz potrafisz diagnozować problemy wdrożeniowe. W tym darmowym podglądzie znajdziesz przykładowe pytania z zestawu 42 zagadnień.

Fiszki obejmują Dockerfile, zarządzanie kontenerami i danymi, sieci, Docker Compose oraz bezpieczeństwo. To praktyczna powtórka przed rozmową dla osób pracujących z lokalnymi środowiskami i procesami deploymentu.

Darmowy start

Pierwsze 20 odpowiedzi są dostępne od razu

Przeglądaj pełną listę 42 pytań. Pełne odpowiedzi, przykłady kodu i materiały do nauki odblokujesz w panelu.

Odblokuj 22 odpowiedzi

Podstawy Docker i Dockerfile

Czym jest Docker i jakie problemy rozwiązuje?

Odpowiedź w 30 sekund: Docker to platforma do konteneryzacji aplikacji, która pakuje aplikację wraz z wszystkimi jej zależnościami w izolowane kontenery. Rozwiązuje problem "u mnie działa" - zapewnia, że aplikacja będzie działać identycznie na każdym środowisku, od laptopa programisty po serwer produkcyjny.

Odpowiedź w 2 minuty: Docker to otwarta platforma do tworzenia, wdrażania i uruchamiania aplikacji w kontenerach. Kontenery umożliwiają pakowanie aplikacji wraz z wszystkimi niezbędnymi bibliotekami, zależnościami i plikami konfiguracyjnymi w standardową jednostkę, która może działać na dowolnym systemie obsługującym Dockera.

Docker rozwiązuje kilka kluczowych problemów w rozwoju oprogramowania. Po pierwsze, eliminuje różnice między środowiskami developerskim, testowym i produkcyjnym - jeśli działa w kontenerze na laptopie, będzie działać identycznie na serwerze. Po drugie, upraszcza zarządzanie zależnościami - wszystkie wymagane biblioteki i wersje są zawarte w obrazie. Po trzecie, umożliwia szybkie skalowanie aplikacji i efektywne wykorzystanie zasobów systemowych.

Dodatkowo Docker przyspiesza proces wdrażania aplikacji, ułatwia integrację ciągłą (CI/CD), zwiększa izolację między aplikacjami i ułatwia pracę w architekturze mikroserwisowej. Jest szeroko wykorzystywany w DevOps i stał się standardem w branży IT.

Przykład kodu:

# Sprawdzenie wersji Dockera
docker --version

# Uruchomienie pierwszego kontenera
docker run hello-world

# Wyświetlenie uruchomionych kontenerów
docker ps

Materiały

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

Odpowiedź w 30 sekund: Kontenery dzielą jądro systemu operacyjnego hosta i wirtualizują tylko warstwę aplikacji, podczas gdy maszyny wirtualne (VM) wirtualizują cały system operacyjny wraz ze sprzętem. Kontenery są lżejsze, szybsze w uruchamianiu (sekundy vs minuty) i zużywają znacznie mniej zasobów niż VM.

Odpowiedź w 2 minuty: Główna różnica między kontenerami a maszynami wirtualnymi polega na poziomie wirtualizacji. Maszyny wirtualne wirtualizują cały sprzęt komputera - każda VM ma własny pełny system operacyjny, kernel i alokowane zasoby (RAM, CPU). Wymaga to hypervisora do zarządzania warstwą wirtualizacji. W efekcie VMs są ciężkie (GB rozmiaru), wolno się uruchamiają (minuty) i zużywają dużo zasobów.

Kontenery natomiast dzielą kernel systemu operacyjnego hosta i izolują tylko przestrzeń użytkownika aplikacji. Docker Engine zarządza kontenerami bezpośrednio na systemie hosta, wykorzystując funkcje jądra Linux (namespaces, cgroups) do izolacji. Dzięki temu kontenery są bardzo lekkie (MB rozmiaru), uruchamiają się błyskawicznie (sekundy) i można uruchomić ich setki na jednym hoście.

Kontenery są idealne do aplikacji cloud-native, mikroserwisów i szybkiego skalowania. VMs lepiej sprawdzają się gdy potrzebna jest pełna izolacja systemowa, różne systemy operacyjne lub aplikacje wymagające głębokiej konfiguracji OS. W praktyce często używa się obu technologii - kontenery działające wewnątrz VM w chmurze.

Przykład kodu:

# Kontener uruchamia się w sekundy
time docker run alpine echo "Hello"

# Jeden host może uruchamiać wiele lekkich kontenerów
docker run -d nginx
docker run -d redis
docker run -d postgres

# Sprawdzenie zużycia zasobów przez kontenery
docker stats

Materiały

Czym jest obraz Docker (Docker image)?

Odpowiedź w 30 sekund: Obraz Docker to niemutowalny szablon zawierający wszystko co potrzebne do uruchomienia aplikacji - kod, runtime, biblioteki, zmienne środowiskowe i pliki konfiguracyjne. Obrazy są budowane z warstw (layers) i służą jako podstawa do tworzenia kontenerów.

Odpowiedź w 2 minuty: Obraz Docker to read-only template, który definiuje jak powinien wyglądać kontener. Można go porównać do klasy w programowaniu obiektowym - obraz to definicja, a kontener to instancja tej definicji. Obrazy są budowane na podstawie instrukcji zawartych w pliku Dockerfile.

Kluczową cechą obrazów jest ich warstwowa architektura. Każda instrukcja w Dockerfile tworzy nową warstwę, która jest cache'owana. Jeśli podczas kolejnego buildu określona warstwa się nie zmieniła, Docker wykorzysta wersję z cache, co znacznie przyspiesza proces budowania. Warstwy są współdzielone między obrazami - jeśli kilka obrazów bazuje na tym samym obrazie podstawowym (np. Ubuntu), ta warstwa jest przechowywana tylko raz.

Obrazy mogą być przechowywane w rejestrach takich jak Docker Hub, które działają jak "GitHub dla obrazów Docker". Możesz pobierać (pull) publiczne obrazy lub publikować (push) własne. Obrazy są oznaczane tagami (np. nginx:latest, node:18-alpine) do wersjonowania. Dzięki immutability obrazów mamy pewność, że aplikacja zawsze uruchomi się w identycznym środowisku.

Przykład kodu:

# Pobranie obrazu z Docker Hub
docker pull nginx:latest

# Wyświetlenie lokalnych obrazów
docker images

# Zbudowanie własnego obrazu z Dockerfile
docker build -t moja-aplikacja:1.0 .

# Wyświetlenie historii warstw obrazu
docker history nginx

# Usunięcie obrazu
docker rmi nginx:latest

Materiały

Czym jest kontener Docker?

Odpowiedź w 30 sekund: Kontener Docker to działająca instancja obrazu Docker - izolowany proces z własnym systemem plików, siecią i przestrzenią procesów. Kontenery są lekkie, przenośne i zawierają wszystko co potrzebne do uruchomienia aplikacji, działając konsekwentnie w każdym środowisku.

Odpowiedź w 2 minuty: Kontener to działająca instancja obrazu Docker, podobnie jak obiekt jest instancją klasy w programowaniu. Gdy uruchamiasz obraz poprzez docker run, Docker tworzy kontener - izolowany proces działający w przestrzeni użytkownika systemu operacyjnego. Każdy kontener ma własny system plików (pochodzący z obrazu), własną sieć wirtualną i izolowaną przestrzeń procesów.

Kontenery wykorzystują mechanizmy jądra Linux - namespaces do izolacji (PID, network, mount, UTS, IPC, user) i cgroups do ograniczania zasobów (CPU, pamięć, I/O). Dzięki temu kontener "myśli", że jest jedynym procesem w systemie, mimo że dzieli kernel z innymi kontenerami. Ta izolacja zapewnia bezpieczeństwo i przewidywalność bez overhead'u pełnej wirtualizacji.

Kontenery są efemeryczne - zaprojektowane do bycia tworzonymi, niszczonymi i odtwarzanymi. Dane wewnątrz kontenera są tracone po jego usunięciu, chyba że używasz wolumenów (volumes) lub bind mounts do persystencji. Stan aplikacji powinien być przechowywany poza kontenerem. To podejście "cattle not pets" ułatwia skalowanie i orkiestrację.

Przykład kodu:

# Utworzenie i uruchomienie kontenera
docker run -d --name moj-nginx -p 8080:80 nginx

# Wyświetlenie uruchomionych kontenerów
docker ps

# Wyświetlenie wszystkich kontenerów (także zatrzymanych)
docker ps -a

# Zatrzymanie kontenera
docker stop moj-nginx

# Uruchomienie zatrzymanego kontenera
docker start moj-nginx

# Usunięcie kontenera
docker rm moj-nginx

# Wykonanie komendy wewnątrz działającego kontenera
docker exec -it moj-nginx bash

Materiały

Co to jest Docker Hub i do czego służy?

Odpowiedź w 30 sekund: Docker Hub to publiczny rejestr obrazów Docker - największe repozytorium kontenerów na świecie. Umożliwia przechowywanie, udostępnianie i pobieranie obrazów Docker, zarówno oficjalnych (np. nginx, postgres) jak i stworzonych przez społeczność czy prywatnych.

Odpowiedź w 2 minuty: Docker Hub to hostowany przez Docker rejestr kontenerów, działający jako centralne repozytorium dla obrazów Docker. Jest to domyślne miejsce, z którego Docker pobiera obrazy przy użyciu komendy docker pull. Można go porównać do GitHub dla kodu - tylko że zamiast repozytoriów kodu przechowuje gotowe do uruchomienia obrazy kontenerów.

Docker Hub oferuje miliony publicznych obrazów, w tym oficjalne obrazy dla popularnych technologii (Node.js, Python, PostgreSQL, Redis, etc.), weryfikowane przez Docker Inc. Możesz też tworzyć własne repozytoria - darmowe konto oferuje nieograniczoną liczbę publicznych repozytoriów oraz jedno prywatne. Płatne plany pozwalają na więcej prywatnych repozytoriów i zaawansowane funkcje zespołowe.

Docker Hub integruje się z GitHub i Bitbucket, umożliwiając automatyczne budowanie obrazów (Automated Builds) po każdym push do repozytorium kodu. Wspiera także webhooks do automatyzacji workflow CI/CD. Alternatywami dla Docker Hub są AWS ECR, Google Container Registry, Azure Container Registry czy prywatne rejestry oparte na Docker Registry.

Przykład kodu:

# Wyszukiwanie obrazów na Docker Hub
docker search postgres

# Pobranie oficjalnego obrazu
docker pull postgres:15

# Logowanie do Docker Hub
docker login

# Tagowanie obrazu przed wysłaniem
docker tag moja-aplikacja:latest username/moja-aplikacja:1.0

# Wysłanie obrazu do Docker Hub
docker push username/moja-aplikacja:1.0

# Pobranie prywatnego obrazu
docker pull username/prywatny-obraz:latest

Materiały

Jak sprawdzić zainstalowaną wersję Dockera?

Odpowiedź w 30 sekund: Użyj komendy docker --version lub docker version aby sprawdzić wersję Dockera. Pierwsza komenda pokazuje skróconą informację, druga wyświetla szczegółowe informacje o kliencie i serwerze Docker (Docker Engine), w tym wersje API, Go runtime i system operacyjny.

Odpowiedź w 2 minuty: Docker składa się z dwóch głównych komponentów - klienta (Docker CLI) i serwera (Docker Engine/daemon). Komenda docker --version pokazuje tylko wersję zainstalowanego klienta w uproszczonej formie, np. "Docker version 24.0.7, build afdd53b". Jest to wystarczające do szybkiego sprawdzenia wersji.

Komenda docker version (bez podwójnego myślnika) wyświetla znacznie więcej informacji - oddzielnie dla klienta i serwera. Pokazuje wersję silnika Docker, wersję API (ważne przy kompatybilności), wersję Go użytą do kompilacji, system operacyjny i architekturę. Jeśli daemon nie jest uruchomiony lub jest problem z połączeniem, zobaczysz tylko informacje o kliencie.

Dodatkowo komenda docker info dostarcza szczegółowych informacji o całej instalacji Docker - liczbę kontenerów i obrazów, driver storage, ustawienia sieci, pluginy, informacje o Swarm i wiele więcej. Jest to przydatne przy diagnozowaniu problemów i weryfikacji konfiguracji systemu Docker.

Przykład kodu:

# Szybkie sprawdzenie wersji
docker --version
# Output: Docker version 24.0.7, build afdd53b

# Szczegółowe informacje o wersji klienta i serwera
docker version

# Kompleksowe informacje o instalacji Docker
docker info

# Sprawdzenie wersji Docker Compose
docker-compose --version

# Sprawdzenie wersji Docker Compose V2 (plugin)
docker compose version

Materiały

Czym jest Dockerfile i jakie ma zastosowanie?

Odpowiedź w 30 sekund: Dockerfile to tekstowy plik zawierający instrukcje do automatycznego budowania obrazu Docker. Definiuje obraz bazowy, kroki instalacji zależności, kopiowanie plików aplikacji i konfigurację środowiska uruchomieniowego. Jest to "przepis" na stworzenie reprodukowalnego obrazu aplikacji.

Odpowiedź w 2 minuty: Dockerfile to plik tekstowy (bez rozszerzenia) zawierający serię instrukcji, które Docker wykonuje sekwencyjnie aby zbudować obraz. Każda instrukcja tworzy nową warstwę w obrazie, co umożliwia cache'owanie i optymalizację. Dockerfile zapewnia Infrastructure as Code - całe środowisko aplikacji jest zdefiniowane w kodzie, wersjonowane w Git i łatwe do reprodukcji.

Typowy Dockerfile zaczyna się od instrukcji FROM definiującej obraz bazowy (np. node:18, python:3.11-slim). Następnie używa instrukcji jak WORKDIR (ustawienie katalogu roboczego), COPY/ADD (kopiowanie plików), RUN (wykonanie komend podczas buildu jak instalacja pakietów), ENV (zmienne środowiskowe), EXPOSE (dokumentacja portów) i CMD/ENTRYPOINT (definicja domyślnej komendy uruchomieniowej).

Dockerfile promuje best practices - pozwala na wieloetapowe buildy (multi-stage builds) do optymalizacji rozmiaru, wykorzystuje .dockerignore do wykluczenia niepotrzebnych plików, umożliwia parametryzację przez ARG i budowanie dedykowanych obrazów dla różnych środowisk. Jest fundamentem automatyzacji CI/CD - ten sam Dockerfile tworzy identyczne obrazy na każdym etapie pipeline'u.

Przykład kodu:

# Obraz bazowy
FROM node:18-alpine

# Ustawienie katalogu roboczego
WORKDIR /app

# Kopiowanie plików package.json
COPY package*.json ./

# Instalacja zależności
RUN npm ci --only=production

# Kopiowanie kodu aplikacji
COPY . .

# Port na którym aplikacja nasłuchuje
EXPOSE 3000

# Komenda uruchomieniowa
CMD ["node", "server.js"]
# Zbudowanie obrazu z Dockerfile
docker build -t moja-app:1.0 .

# Build z konkretnym plikiem (nie Dockerfile)
docker build -f Dockerfile.prod -t moja-app:prod .

# Build z argumentami
docker build --build-arg NODE_ENV=production -t moja-app .

Materiały

Jaka jest różnica między instrukcjami RUN, CMD i ENTRYPOINT?

Odpowiedź w 30 sekund: RUN wykonuje komendy podczas budowania obrazu i tworzy nową warstwę (np. instalacja pakietów). CMD definiuje domyślną komendę uruchamianą gdy startuje kontener, można ją nadpisać. ENTRYPOINT określa główny proces kontenera, którego nie można łatwo nadpisać - używa się go gdy kontener ma działać jak executable.

Odpowiedź w 2 minuty: RUN wykonuje się podczas fazy budowania obrazu (docker build). Każda instrukcja RUN tworzy nową warstwę w obrazie i jest cache'owana. Używamy RUN do instalacji pakietów, aktualizacji systemu, tworzenia katalogów czy kompilacji kodu. Przykład: RUN apt-get update && apt-get install -y curl. Można mieć wiele instrukcji RUN w Dockerfile.

CMD definiuje domyślną komendę i/lub parametry, które zostaną wykonane gdy kontener startuje. W Dockerfile może być tylko jedna instrukcja CMD (jeśli jest więcej, liczy się ostatnia). CMD łatwo nadpisać podając argumenty do docker run - na przykład docker run ubuntu ls nadpisze domyślne CMD. CMD jest idealne dla aplikacji, które mogą być uruchamiane na różne sposoby.

ENTRYPOINT określa główny wykonywalny proces kontenera. W przeciwieństwie do CMD, ENTRYPOINT nie jest łatwo nadpisywane - argumenty przekazane do docker run są dodawane do ENTRYPOINT, a nie go zastępują. ENTRYPOINT używamy gdy chcemy, aby kontener działał jak konkretne narzędzie/komenda. Często łączy się ENTRYPOINT (główna komenda) z CMD (domyślne parametry): ENTRYPOINT to "executable", CMD to "default parameters".

Przykład kodu:

# RUN - wykonuje się podczas budowania
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y python3
RUN mkdir /app

# CMD - domyślna komenda, łatwo nadpisywana
FROM node:18
WORKDIR /app
COPY . .
CMD ["npm", "start"]
# docker run app          -> uruchomi npm start
# docker run app npm test -> uruchomi npm test (CMD nadpisane)

# ENTRYPOINT - główny proces, trudny do nadpisania
FROM alpine
ENTRYPOINT ["ping"]
CMD ["localhost"]
# docker run app           -> ping localhost
# docker run app google.pl -> ping google.pl (CMD nadpisane, ENTRYPOINT nie)

# ENTRYPOINT + CMD razem - best practice
FROM python:3.11
ENTRYPOINT ["python", "app.py"]
CMD ["--help"]
# docker run app           -> python app.py --help
# docker run app --verbose -> python app.py --verbose

Materiały

Czym różni się instrukcja COPY od ADD w Dockerfile?

Odpowiedź w 30 sekund: COPY to prosta instrukcja kopiująca pliki i katalogi z hosta do obrazu. ADD ma dodatkowe funkcje - automatycznie rozpakowuje archiwa tar i pobiera pliki z URL. W praktyce zaleca się używać COPY dla przejrzystości, a ADD tylko gdy potrzebna jest automatyczna ekstrakcja archiwów.

Odpowiedź w 2 minuty: COPY jest prostszą i bardziej przewidywalną instrukcją - kopiuje pliki i katalogi z lokalnego systemu plików (build context) do obrazu Docker. Składnia: COPY <źródło> <cel>. Robi dokładnie to co nazwa sugeruje, bez niespodzianek. Jest to zalecane podejście zgodnie z Docker best practices, ponieważ jest jasne i czytelne.

ADD ma rozszerzoną funkcjonalność - oprócz kopiowania plików również: (1) automatycznie rozpakowuje lokalne archiwa tar (tar, gzip, bzip2, xz) do katalogu docelowego, (2) może pobierać pliki bezpośrednio z URL. Przykład: ADD https://example.com/file.tar.gz /app/ pobierze i skopiuje plik (ale nie rozpakuje URL!). ADD archive.tar.gz /app/ skopiuje i automatycznie rozpakuje archiwum.

Te dodatkowe funkcje ADD mogą prowadzić do nieoczekiwanego zachowania i utrudniać debugowanie. Jeśli skopiujesz archiwum tar używając ADD, zostanie ono automatycznie rozpakowane - co może nie być intencją. Dlatego Docker zaleca: używaj COPY chyba że naprawdę potrzebujesz funkcji ADD (głównie automatycznej ekstrakcji tar). Dla URL lepiej użyć RUN z wget/curl dla większej kontroli.

Przykład kodu:

# COPY - zalecane dla zwykłego kopiowania plików
FROM node:18
WORKDIR /app

# Kopiowanie pojedynczego pliku
COPY package.json .

# Kopiowanie wielu plików
COPY package.json package-lock.json ./

# Kopiowanie całego katalogu
COPY src/ ./src/

# Kopiowanie wszystkiego (respektuje .dockerignore)
COPY . .

# ADD - używaj tylko gdy potrzebna jest specjalna funkcjonalność
FROM ubuntu:22.04

# Automatyczne rozpakowanie archiwum tar
ADD myarchive.tar.gz /app/
# Plik zostanie rozpakowany w /app/

# Pobieranie z URL (lepiej użyć RUN curl/wget)
ADD https://example.com/config.json /etc/app/

# Prawidłowe użycie dla URL - większa kontrola
RUN curl -L https://example.com/file.tar.gz | tar xz -C /app

Materiały

Co oznacza instrukcja EXPOSE w Dockerfile?

Odpowiedź w 30 sekund: EXPOSE dokumentuje na jakich portach kontener nasłuchuje w czasie działania. To tylko metadata - nie publikuje portów na zewnątrz. Aby faktycznie udostępnić port, musisz użyć flagi -p lub -P podczas docker run. EXPOSE służy jako dokumentacja dla użytkowników obrazu.

Odpowiedź w 2 minuty: EXPOSE to instrukcja dokumentacyjna w Dockerfile, która informuje użytkowników obrazu (i innych programistów) na jakich portach aplikacja w kontenerze będzie nasłuchiwać. Składnia: EXPOSE <port> [<port>/<protocol>...]. Można określić protokół (TCP/UDP), domyślnie jest TCP. Przykład: EXPOSE 80, EXPOSE 443/tcp, EXPOSE 53/udp.

Ważne jest zrozumienie, że EXPOSE sam w sobie NIE publikuje portów na hosta. To tylko metadata - swojego rodzaju dokumentacja w kodzie. Kontener nadal będzie nasłuchiwał na tych portach wewnętrznie, ale nie będą one dostępne z zewnątrz chyba że explicite je zmapujesz podczas uruchamiania kontenera.

Aby faktycznie udostępnić porty, używasz flag podczas docker run: -p <host_port>:<container_port> mapuje konkretny port, lub -P (wielkie P) automatycznie mapuje wszystkie porty zadeklarowane przez EXPOSE na losowe porty hosta. EXPOSE jest także wykorzystywane przez Docker Compose i orkiestratory jak Kubernetes do automatycznej konfiguracji sieci między kontenerami. Jest to dobra praktyka - zawsze dokumentuj porty które Twoja aplikacja używa.

Przykład kodu:

# Definicja EXPOSE w Dockerfile
FROM node:18
WORKDIR /app
COPY . .

# Dokumentacja - aplikacja nasłuchuje na porcie 3000
EXPOSE 3000

CMD ["node", "server.js"]
# Uruchomienie bez publikacji portu - port NIE jest dostępny z hosta
docker run moja-app
# Aplikacja działa wewnątrz kontenera na :3000, ale nie dostępna na hoście

# Mapowanie portu explicite: host:container
docker run -p 8080:3000 moja-app
# Aplikacja dostępna na localhost:8080 -> kieruje do :3000 w kontenerze

# Automatyczne mapowanie wszystkich EXPOSE na losowe porty hosta
docker run -P moja-app
# Docker mapuje :3000 na losowy port np. 32768

# Sprawdzenie zmapowanych portów
docker ps
docker port <container_id>
# EXPOSE z wieloma portami i protokołami
FROM nginx
EXPOSE 80/tcp
EXPOSE 443/tcp
EXPOSE 53/udp

Materiały

Jak działa wieloetapowy build (multi-stage build) i kiedy go używać?

Odpowiedź w 30 sekund: Multi-stage build pozwala używać wielu instrukcji FROM w jednym Dockerfile, gdzie każdy stage może mieć własny obraz bazowy. Służy to do optymalizacji - w pierwszych stage'ach kompilujesz/budujesz aplikację, a w ostatnim stage kopiujesz tylko artefakty, bez narzędzi buildowych. Rezultat: drastycznie mniejszy finalny obraz.

Odpowiedź w 2 minuty: Multi-stage build to technika wprowadzona w Docker 17.05, która pozwala na tworzenie wielu etapów (stages) w jednym Dockerfile, gdzie każdy etap może bazować na innym obrazie. Każda instrukcja FROM rozpoczyna nowy stage. Możesz kopiować artefakty między stage'ami używając COPY --from=<stage>. Tylko ostatni stage tworzy finalny obraz - poprzednie są odrzucane.

Główne zastosowanie to optymalizacja rozmiaru obrazu. Na przykład przy aplikacji Go czy Java potrzebujesz kompilatora i narzędzi buildowych podczas budowania, ale w środowisku runtime wystarczy tylko skompilowany binary. Bez multi-stage musiałbyś includować cały toolchain w finalnym obrazie (setki MB). Z multi-stage: pierwszy stage kompiluje aplikację używając pełnego obrazu (golang:1.21, maven:3.9), a drugi stage kopiuje tylko skompilowany binary do minimalnego obrazu (alpine, distroless).

Dodatkowe korzyści to lepsze bezpieczeństwo (mniej zainstalowanych pakietów = mniejsza powierzchnia ataku), szybszy deployment (mniejszy obraz = szybsze pull/push) i czystszy Dockerfile. Można też używać multi-stage do różnych celów - stage do testów, stage do developmentu, stage do produkcji. Każdy stage może być budowany osobno używając --target flag.

Przykład kodu:

# Stage 1: Build stage - duży obraz z narzędziami
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp

# Stage 2: Production stage - minimalny obraz
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# Kopiowanie tylko binarki ze stage'a builder
COPY --from=builder /app/myapp .
EXPOSE 8080
CMD ["./myapp"]
# Multi-stage dla Node.js z oddzielnymi stages
FROM node:18 AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:18 AS builder
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:18-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=dependencies /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]
# Budowanie całego multi-stage Dockerfile
docker build -t myapp:prod .

# Budowanie tylko konkretnego stage (np. do testów)
docker build --target builder -t myapp:builder .

# Porównanie rozmiaru
# Obraz z golang:1.21 (z kompilatorami): ~800MB
# Obraz finalny alpine z binary: ~15MB
docker images

Materiały

Jak zoptymalizować rozmiar obrazu Docker?

Odpowiedź w 30 sekund: Użyj minimalnych obrazów bazowych (alpine, distroless), multi-stage builds do odrzucenia build dependencies, łącz komendy RUN aby zmniejszyć liczbę warstw, dodaj .dockerignore, usuń cache i temporary files, instaluj tylko production dependencies. Te techniki mogą zmniejszyć obraz z GB do dziesiątek MB.

Odpowiedź w 2 minuty: Optymalizacja rozmiaru obrazu Docker jest kluczowa dla szybszego deploymentu, mniejszego zużycia bandwidth i lepszego bezpieczeństwa. Pierwsza zasada: wybierz najmniejszy możliwy obraz bazowy. Zamiast ubuntu (78MB) użyj alpine (5MB) lub distroless (jeszcze mniejsze). Dla Node.js: node:18-alpine zamiast node:18 oszczędza setki MB.

Druga technika to multi-stage builds - buduj aplikację w pełnym obrazie z narzędziami, a do finalnego obrazu kopiuj tylko artefakty. Trzecia: łącz komendy RUN w jeden layer i czyść cache w tej samej warstwie. Zamiast trzech RUN apt-get install, zrób jeden RUN apt-get update && apt-get install -y package1 package2 && rm -rf /var/lib/apt/lists/*. Każdy RUN tworzy warstwę - mniej warstw = mniejszy obraz.

Czwarta: użyj .dockerignore aby wykluczyć niepotrzebne pliki (node_modules, .git, testy, dokumentacja). Piąta: dla Node.js/Python instaluj tylko production dependencies (npm ci --only=production, pip install --no-cache-dir). Szósta: rozważ narzędzia jak dive (analiza warstw obrazu) lub docker-slim (automatyczna optymalizacja). Optymalizacja może zmniejszyć obrazy Node.js z 1GB do 50MB, Go z 800MB do 10MB.

Przykład kodu:

# ❌ ZŁY przykład - duży obraz
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
CMD ["npm", "start"]
# Rozmiar: ~1.1GB

# ✅ DOBRY przykład - zoptymalizowany
# Stage 1: Builder
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# Stage 2: Production
FROM node:18-alpine
RUN apk add --no-cache tini
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["node", "dist/server.js"]
# Rozmiar: ~150MB (7x mniejszy!)
# Optymalizacja dla aplikacji Go
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o app

FROM scratch
COPY --from=builder /app/app /app
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 8080
ENTRYPOINT ["/app"]
# Rozmiar: ~10MB (80x mniejszy niż z golang:1.21!)
# Łączenie RUN i czyszczenie cache w jednej warstwie
FROM ubuntu:22.04
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        python3 \
        python3-pip && \
    rm -rf /var/lib/apt/lists/* && \
    pip3 install --no-cache-dir flask
# .dockerignore - wykluczenie niepotrzebnych plików
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.DS_Store
*.md
tests/
docs/

# Analiza warstw obrazu
docker history moja-app
dive moja-app  # wymaga instalacji dive

# Porównanie rozmiaru
docker images | grep moja-app

Materiały

Czym jest .dockerignore i dlaczego jest ważny?

Odpowiedź w 30 sekund: .dockerignore to plik definiujący które pliki i katalogi powinny być wykluczone z build context podczas budowania obrazu Docker. Działa jak .gitignore. Pomija niepotrzebne pliki (node_modules, .git, testy), co przyspiesza build, zmniejsza rozmiar obrazu i poprawia bezpieczeństwo (nie kopiuje sekretów).

Odpowiedź w 2 minuty: .dockerignore to plik tekstowy umieszczany w głównym katalogu projektu (obok Dockerfile), który określa wzorce plików i katalogów do wykluczenia z build context. Build context to wszystkie pliki które Docker wysyła do daemon podczas budowania obrazu. Bez .dockerignore Docker wysyła WSZYSTKIE pliki z katalogu, co może być bardzo nieefektywne.

Główne korzyści używania .dockerignore: (1) Szybsze buildy - mniej danych do transferu do Docker daemon, szczególnie ważne przy dużych projektach z node_modules czy .git. (2) Mniejszy rozmiar obrazu - wykluczając niepotrzebne pliki zapobiegasz ich przypadkowemu skopiowaniu do obrazu przez COPY . .. (3) Lepsze bezpieczeństwo - zapobiega przypadkowemu includeowaniu wrażliwych plików (.env, klucze SSH, credentials). (4) Czystszy cache - Docker nie invaliduje cache'a warstw gdy zmieniają się zignorowane pliki.

Składnia .dockerignore jest podobna do .gitignore: każda linia to wzorzec. * oznacza wildcard, ** rekursywnie, ! neguje wzorzec. Przykład: *.md ignoruje wszystkie pliki markdown, !README.md robi wyjątek dla README. Typowe wpisy to: node_modules, .git, pliki IDE (.vscode, .idea), logi, pliki tymczasowe, dokumentacja, testy i pliki środowiskowe.

Przykład kodu:

# .dockerignore dla projektu Node.js

# Dependencies
node_modules
npm-debug.log
yarn-error.log

# Testing
coverage
*.test.js
tests/
__tests__/

# Environment variables (bezpieczeństwo!)
.env
.env.local
.env.*.local

# Git
.git
.gitignore
.gitattributes

# IDE
.vscode
.idea
*.swp
*.swo
.DS_Store

# CI/CD
.github
.gitlab-ci.yml
.travis.yml

# Documentation
*.md
docs/
!README.md

# Docker
Dockerfile*
docker-compose*.yml
.dockerignore

# Build artifacts
dist
build
*.log

# Temporary files
tmp
temp
*.tmp
# Dockerfile wykorzystujący .dockerignore
FROM node:18-alpine
WORKDIR /app

# .dockerignore sprawia że COPY nie kopiuje node_modules, .git, etc
COPY package*.json ./
RUN npm ci --only=production

# COPY . . kopiuje tylko potrzebne pliki (dzięki .dockerignore)
COPY . .

EXPOSE 3000
CMD ["node", "server.js"]
# .dockerignore dla projektu Python

# Python
__pycache__
*.py[cod]
*$py.class
*.so
.Python
venv/
env/
ENV/

# Testing
.pytest_cache
.coverage
htmlcov/

# Distribution
dist/
build/
*.egg-info/

# IDE & OS
.vscode
.idea
.DS_Store

# Docs & configs
*.md
.git
.gitignore

Materiały

Docker - Zarządzanie kontenerami i wolumeny

Jak uruchomić kontener w tle (tryb detached)?

Odpowiedź w 30 sekund: Aby uruchomić kontener w tle, należy użyć flagi -d lub --detach z poleceniem docker run. Kontener będzie działał w tle bez blokowania terminala, a Docker zwróci ID kontenera.

Odpowiedź w 2 minuty: Tryb detached (odłączony) pozwala na uruchomienie kontenera w tle, dzięki czemu terminal pozostaje dostępny do wykonywania innych poleceń. Jest to standardowy sposób uruchamiania kontenerów produkcyjnych, takich jak serwery webowe czy bazy danych.

Po uruchomieniu kontenera w trybie detached, Docker wyświetla ID kontenera i zwraca kontrolę nad terminalem. Kontener nadal działa w tle, a jego logi można podejrzeć używając docker logs. Można również połączyć się z działającym kontenerem za pomocą docker attach lub docker exec.

Dodatkowe flagi, takie jak --name pozwalają nadać kontenerowi czytelną nazwę, a --restart określa politykę restartowania kontenera w przypadku awarii lub restartu systemu.

Przykład kodu:

# Uruchomienie kontenera Nginx w tle
docker run -d nginx

# Uruchomienie z nazwą i mapowaniem portów
docker run -d --name moj-nginx -p 8080:80 nginx

# Uruchomienie z automatycznym restartem
docker run -d --name moj-nginx --restart unless-stopped -p 8080:80 nginx

# Sprawdzenie czy kontener działa
docker ps

Materiały

Jak zatrzymać i usunąć działający kontener?

Odpowiedź w 30 sekund: Kontener zatrzymuje się poleceniem docker stop [ID/nazwa], które wysyła sygnał SIGTERM, a po upływie czasu SIGKILL. Usunięcie wymaga najpierw zatrzymania kontenera, a następnie wykonania docker rm [ID/nazwa], lub można użyć docker rm -f do wymuszenia usunięcia działającego kontenera.

Odpowiedź w 2 minuty: Zatrzymywanie kontenera przebiega w dwóch fazach: najpierw Docker wysyła do procesu głównego sygnał SIGTERM (graceful shutdown), dając aplikacji czas na uporządkowane zakończenie (domyślnie 10 sekund). Jeśli kontener się nie zatrzyma, Docker wysyła SIGKILL, który natychmiast kończy proces. Czas oczekiwania można zmienić flagą --time.

Po zatrzymaniu kontenera można go usunąć używając docker rm. Zatrzymany kontener nadal zajmuje miejsce na dysku, przechowując swoją warstwę zapisu i metadane. Usunięcie kontenera jest nieodwracalne - tracimy wszystkie zmiany w systemie plików kontenera (chyba że używamy wolumenów).

Istnieją skróty ułatwiające zarządzanie: docker rm -f wymusza zatrzymanie i usunięcie w jednym kroku, a docker container prune usuwa wszystkie zatrzymane kontenery naraz. Flaga --rm przy uruchamianiu kontenera powoduje jego automatyczne usunięcie po zatrzymaniu.

Przykład kodu:

# Zatrzymanie kontenera (graceful shutdown)
docker stop moj-kontener

# Zatrzymanie z niestandardowym timeoutem (3 sekundy)
docker stop --time 3 moj-kontener

# Natychmiastowe zabicie kontenera
docker kill moj-kontener

# Usunięcie zatrzymanego kontenera
docker rm moj-kontener

# Wymuszenie zatrzymania i usunięcia
docker rm -f moj-kontener

# Usunięcie wszystkich zatrzymanych kontenerów
docker container prune

# Uruchomienie kontenera z automatycznym usuwaniem po zatrzymaniu
docker run --rm nginx

Materiały

Jak podejrzeć logi kontenera?

Odpowiedź w 30 sekund: Logi kontenera wyświetla się poleceniem docker logs [ID/nazwa]. Domyślnie pokazuje wszystkie logi od uruchomienia kontenera. Można używać flag jak -f do podążania za logami w czasie rzeczywistym, --tail do wyświetlenia ostatnich linii, czy --since do filtrowania po czasie.

Odpowiedź w 2 minuty: Docker przechwytuje wszystko, co aplikacja w kontenerze wysyła na strumienie stdout i stderr, i przechowuje to jako logi. Polecenie docker logs pozwala na wgląd w te logi, co jest kluczowe przy debugowaniu problemów z aplikacją.

Flaga -f lub --follow działa podobnie jak tail -f w Linuxie - wyświetla logi w czasie rzeczywistym, co jest przydatne podczas monitorowania działającej aplikacji. Można ograniczyć liczbę wyświetlanych linii używając --tail n, gdzie n to liczba ostatnich linii. Filtrowanie czasowe umożliwiają flagi --since i --until, które przyjmują timestamp lub relatywny czas (np. "2h" dla ostatnich 2 godzin).

Każda linia logu może zawierać timestamp (dodawany flagą -t) oraz informację o strumieniu (stdout/stderr). W środowiskach produkcyjnych często używa się zewnętrznych systemów do agregacji logów (jak ELK stack, Splunk), ponieważ logi Docker są przechowywane lokalnie i mogą zająć dużo miejsca.

Warto wiedzieć, że domyślny sterownik logowania (json-file) może powodować problemy z zajętością dysku. Można skonfigurować rotację logów lub użyć innych sterowników logowania.

Przykład kodu:

# Wyświetlenie wszystkich logów kontenera
docker logs moj-kontener

# Podążanie za logami w czasie rzeczywistym
docker logs -f moj-kontener

# Wyświetlenie ostatnich 100 linii
docker logs --tail 100 moj-kontener

# Logi z ostatnich 2 godzin
docker logs --since 2h moj-kontener

# Logi z timestampami
docker logs -t moj-kontener

# Kombinacja: ostatnie 50 linii z podążaniem i timestampami
docker logs --tail 50 -ft moj-kontener

# Logi od konkretnego czasu
docker logs --since "2024-01-15T10:00:00" moj-kontener

# Sprawdzenie konfiguracji logowania kontenera
docker inspect --format='{{.HostConfig.LogConfig}}' moj-kontener

Materiały

Jak wejść do działającego kontenera (uruchomić sesję shell)?

Odpowiedź w 30 sekund: Do działającego kontenera wchodzi się poleceniem docker exec -it [ID/nazwa] /bin/bash lub /bin/sh w zależności od dostępnej powłoki. Flagi -i (interactive) i -t (tty) zapewniają interaktywną sesję terminalową.

Odpowiedź w 2 minuty: Polecenie docker exec pozwala uruchomić nowy proces w działającym kontenerze. Jest to preferowana metoda do debugowania i zarządzania kontenerami, ponieważ nie zakłóca głównego procesu kontenera. Flaga -i utrzymuje stdin otwarty, a -t alokuje pseudo-TTY, co razem zapewnia pełną interaktywną sesję shell.

Wybór powłoki zależy od obrazu bazowego: obrazy oparte na Debianie/Ubuntu zazwyczaj mają /bin/bash, podczas gdy minimalistyczne obrazy Alpine Linux używają /bin/sh. Można sprawdzić dostępne powłoki próbując różnych wariantów lub używając which bash.

Alternatywnie można użyć docker attach, ale ma to istotną różnicę: attach podłącza się do głównego procesu kontenera (PID 1), więc wyjście z sesji (Ctrl+D) zatrzyma kontener. Z kolei exec uruchamia nowy proces, więc wyjście nie wpływa na działanie kontenera. Exec jest bezpieczniejszy i bardziej elastyczny.

Można również uruchamiać pojedyncze komendy bez interaktywnej sesji: docker exec moj-kontener ls /app, co jest przydatne w skryptach i automatyzacji.

Przykład kodu:

# Wejście do kontenera z Bash (Ubuntu/Debian)
docker exec -it moj-kontener /bin/bash

# Wejście do kontenera z sh (Alpine Linux)
docker exec -it moj-kontener /bin/sh

# Uruchomienie komendy jako root (jeśli kontener działa jako inny user)
docker exec -it -u root moj-kontener /bin/bash

# Uruchomienie pojedynczej komendy bez interaktywnej sesji
docker exec moj-kontener ls -la /app

# Uruchomienie komendy z określonym katalogiem roboczym
docker exec -it -w /app moj-kontener /bin/bash

# Sprawdzenie dostępnych powłok w kontenerze
docker exec moj-kontener cat /etc/shells

# Alternatywa: attach (UWAGA: wyjście zatrzyma kontener!)
docker attach moj-kontener

# Uruchomienie komendy z własnymi zmiennymi środowiskowymi
docker exec -it -e MOJA_ZMIENNA=wartosc moj-kontener /bin/bash

Materiały

Jak przekazać zmienne środowiskowe do kontenera?

Odpowiedź w 30 sekund: Zmienne środowiskowe przekazuje się używając flagi -e lub --env z docker run: docker run -e ZMIENNA=wartość. Można też użyć --env-file do wczytania zmiennych z pliku. W Dockerfile używa się instrukcji ENV do definiowania domyślnych zmiennych.

Odpowiedź w 2 minuty: Docker oferuje kilka sposobów na przekazanie zmiennych środowiskowych do kontenera. Najprostszy to flaga -e lub --env przy uruchamianiu: docker run -e DB_HOST=localhost -e DB_PORT=5432 moj-obraz. Można podać wiele flag -e dla różnych zmiennych.

Gdy zmiennych jest dużo, wygodniej użyć --env-file, który wczytuje zmienne z pliku tekstowego (format: KLUCZ=wartość w każdej linii). To popularne podejście w aplikacjach twelve-factor, gdzie konfiguracja jest oddzielona od kodu. Pliki .env często zawierają wrażliwe dane (hasła, klucze API), więc powinny być dodane do .gitignore i .dockerignore.

W Dockerfile instrukcja ENV definiuje domyślne zmienne środowiskowe, które będą dostępne podczas budowania obrazu i w uruchomionych kontenerach. Zmienne przekazane przez -e przy uruchamianiu nadpisują te z ENV.

Ważna różnica: ARG w Dockerfile to zmienne dostępne tylko podczas budowania obrazu, nie są one dostępne w uruchomionym kontenerze. ENV tworzy zmienne dostępne zarówno podczas budowania jak i w runtime.

Przykład kodu:

# Przekazanie pojedynczej zmiennej
docker run -e NODE_ENV=production moj-node-app

# Przekazanie wielu zmiennych
docker run -e DB_HOST=postgres -e DB_PORT=5432 -e DB_NAME=mydb moj-app

# Przekazanie zmiennej z systemu hosta
docker run -e USER=$USER moj-app

# Użycie pliku ze zmiennymi środowiskowymi
docker run --env-file .env moj-app

# Wyświetlenie zmiennych środowiskowych w kontenerze
docker exec moj-kontener env

# Sprawdzenie zmiennych środowiskowych zdefiniowanych w obrazie
docker inspect moj-obraz | grep -A 20 Env

Przykład pliku .env:

# Plik .env
NODE_ENV=production
DB_HOST=postgres
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=tajne_haslo
API_KEY=xyz123

Przykład w Dockerfile:

# Domyślne zmienne środowiskowe
ENV NODE_ENV=development
ENV PORT=3000
ENV LOG_LEVEL=info

# Zmienna tylko dla czasu budowania
ARG BUILD_VERSION=1.0.0

Materiały

Jak wylistować wszystkie działające i zatrzymane kontenery?

Odpowiedź w 30 sekund: Polecenie docker ps wyświetla działające kontenery, a docker ps -a (lub --all) pokazuje wszystkie kontenery, włącznie z zatrzymanymi. Można używać filtrów (--filter) i formatowania (--format) do dostosowania wyświetlanych informacji.

Odpowiedź w 2 minuty: Polecenie docker ps jest podstawowym narzędziem do przeglądania kontenerów. Bez żadnych flag pokazuje tylko działające kontenery z informacjami: ID kontenera, obraz, komenda, czas utworzenia, status, porty i nazwa. To odpowiednik ps z systemów Unix, ale dla kontenerów Docker.

Flaga -a lub --all rozszerza wynik o zatrzymane kontenery, co jest przydatne przy debugowaniu - często chcemy zobaczyć kontenery, które zakończyły działanie z błędem. Status kontenera pokazuje jak dawno został zatrzymany i z jakim kodem wyjścia (np. "Exited (1) 2 hours ago" oznacza błąd).

Docker oferuje zaawansowane opcje filtrowania: --filter "status=exited" pokaże tylko zatrzymane kontenery, --filter "name=postgres" znajdzie kontenery po nazwie. Można łączyć wiele filtrów. Flaga -q (quiet) zwraca tylko ID kontenerów, co jest idealne do skryptów: docker rm $(docker ps -aq) usuwa wszystkie kontenery.

Formatowanie wyjścia można dostosować używając --format z szablonem Go. Pozwala to wyświetlić tylko wybrane kolumny lub całkowicie zmienić format (np. do JSON).

Przykład kodu:

# Wyświetlenie działających kontenerów
docker ps

# Wyświetlenie wszystkich kontenerów (włącznie z zatrzymanymi)
docker ps -a

# Wyświetlenie tylko ID kontenerów
docker ps -q

# Wyświetlenie ostatnio utworzonego kontenera
docker ps -l

# Wyświetlenie ostatnich 3 kontenerów
docker ps -n 3

# Filtrowanie po statusie
docker ps -a --filter "status=exited"
docker ps --filter "status=running"

# Filtrowanie po nazwie
docker ps -a --filter "name=postgres"

# Filtrowanie po obrazie
docker ps --filter "ancestor=nginx"

# Niestandardowe formatowanie (tylko nazwa i status)
docker ps -a --format "table {{.Names}}\t{{.Status}}"

# Formatowanie JSON
docker ps --format "{{json .}}"

# Wyświetlenie rozmiaru kontenerów
docker ps -s

# Kombinacja: wszystkie zatrzymane kontenery z Nginx, tylko ID
docker ps -aq --filter "ancestor=nginx" --filter "status=exited"

# Użycie w skryptach - usunięcie wszystkich zatrzymanych kontenerów
docker rm $(docker ps -aq --filter "status=exited")

Materiały

Wolumeny i przechowywanie danych

Czym są wolumeny Docker (Docker volumes)?

Odpowiedź w 30 sekund: Docker volumes to mechanizm persystencji danych, który pozwala przechowywać dane poza warstwą zapisu kontenera. Są zarządzane przez Docker, niezależne od cyklu życia kontenera i mogą być współdzielone między wieloma kontenerami.

Odpowiedź w 2 minuty: Wolumeny Docker to preferowany sposób przechowywania trwałych danych generowanych i używanych przez kontenery. W przeciwieństwie do systemu plików kontenera, który jest ulotny i znika wraz z usunięciem kontenera, wolumeny istnieją niezależnie i przetrwają restart czy usunięcie kontenera.

Docker w pełni zarządza wolumenami - tworzy je w specjalnej lokalizacji na hoście (zwykle /var/lib/docker/volumes/ na Linuxie), obsługuje ich backup, migrację i czyszczenie. Wolumeny można tworzyć jawnie poleceniem docker volume create lub Docker utworzy je automatycznie przy pierwszym użyciu.

Wolumeny oferują kilka kluczowych zalet: są niezależne od platformy (działają identycznie na Linux, Windows, Mac), mogą być współdzielone między wieloma kontenerami jednocześnie, obsługują sterowniki wolumenów do przechowywania w chmurze lub zdalnych systemach, są łatwiejsze w backupie i migracji niż bind mounts, oraz działają zarówno na kontenerach Linux jak i Windows.

Typowe przypadki użycia to bazy danych (PostgreSQL, MongoDB), przechowywanie uploadowanych plików, cache aplikacji, czy współdzielenie konfiguracji między kontenerami. Wolumeny są kluczowe dla aplikacji stanowych (stateful) w Dockerze.

Przykład kodu:

# Utworzenie wolumenu
docker volume create moje-dane

# Wyświetlenie listy wolumenów
docker volume ls

# Szczegóły wolumenu
docker volume inspect moje-dane

# Uruchomienie kontenera z wolumenem
docker run -d --name postgres-db -v moje-dane:/var/lib/postgresql/data postgres

# Utworzenie wolumenu z określonym sterownikiem
docker volume create --driver local --opt type=nfs --opt device=:/path/to/dir moj-nfs

# Uruchomienie z automatycznym utworzeniem wolumenu
docker run -d -v auto-volume:/app/data nginx

# Backup wolumenu do pliku tar
docker run --rm -v moje-dane:/data -v $(pwd):/backup ubuntu tar czf /backup/backup.tar.gz /data

# Restore z backupu
docker run --rm -v moje-dane:/data -v $(pwd):/backup ubuntu tar xzf /backup/backup.tar.gz -C /data --strip 1

# Usunięcie wolumenu (kontener musi być zatrzymany)
docker volume rm moje-dane

# Usunięcie wszystkich nieużywanych wolumenów
docker volume prune

Materiały

21. Jaka jest różnica między wolumenem a bind mount?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
22. Jak utworzyć i używać wolumenu Docker?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
23. Jak dane są persystowane między restartami kontenera?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
24. Kiedy używać tmpfs mount?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi

Sieciowanie i Docker Compose

25. Jakie są domyślne typy sieci w Docker?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
26. Czym różni się sieć bridge od host?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
27. Jak kontenery komunikują się ze sobą w ramach tej samej sieci?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
28. Jak mapować porty między hostem a kontenerem?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
29. Czym jest Docker DNS i jak działa?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
30. Czym jest Docker Compose i kiedy go używać?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
31. Jak zdefiniować wielokontenerową aplikację w docker-compose.yml?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
32. Jaka jest różnica między docker-compose up a docker-compose start?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
33. Jak skalować usługi w Docker Compose?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
34. Jak zarządzać zależnościami między usługami (depends_on)?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi

Bezpieczeństwo

35. Jakie są najlepsze praktyki bezpieczeństwa dla obrazów Docker?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
36. Dlaczego nie należy uruchamiać procesów w kontenerze jako root?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
37. Jak skanować obrazy Docker pod kątem podatności?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
38. Czym jest podpisywanie obrazów Docker (Docker Content Trust)?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi

Optymalizacja i dobre praktyki

39. Jak efektywnie wykorzystać cache warstw podczas budowania obrazu?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
40. Jakie są najlepsze praktyki pisania Dockerfile?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
41. Jak debugować problemy z budowaniem obrazu?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi
42. Kiedy używać Docker a kiedy rozważyć alternatywy (Podman, containerd)?

Odpowiedź dostępna w pełnej wersji. Odblokuj 22 pozostałych odpowiedzi i ucz się z pełnego zestawu.

Odblokuj odpowiedzi

Chcesz poznać wszystkie odpowiedzi?

Uzyskaj pełny dostęp do 42 pytań rekrutacyjnych z Docker oraz pozostałych technologii.

Zobacz plany cenowe