Konteneryzacja aplikacji, czyli podstawy Dockera
20 minut
DevOps/Developer
Junior
Poznaj Docker w kilku prostych krokach

Wprowadzenie do Docker'a
1. Co to jest Docker?
Docker to technologia konteneryzacji, która pozwala na tworzenie, zarządzanie i uruchamianie aplikacji w izolowanych środowiskach zwanych kontenerami. Konteneryzacja natomiast to metoda pakowania aplikacji i jej zależności w jedno przenośne środowisko, które można uruchomić na dowolnym systemie wspierającym Dockera. Dzięki temu aplikacje stają się bardziej przenośne, skalowalne i łatwe w zarządzaniu.
2. Jakie są kluczowe cechy Docker'a?
- Izolacja - Każdy kontener działa w izolowanym środowisku, co zapewnia, że aplikacje nie będą się ze sobą komunikować, póki im na to nie pozwolimy. Ponadto nie dojdzie do kolizji z innymi aplikacj. (np. kolizja mapowania portów)
- Przenośność - Kontenery mogą być uruchamiane na różnych platformach i systemach operacyjnych bez konieczności zmiany kodu. Sama migracja aplikacji jest niemalże autoamtyczna.
- Wydajności - Kontenery Docker'a w porównaniu do maszyn wirtualnych są lekkie i wydajne z uwagi na fakt, że wykorzystują Kernel Hosta.
- Skalowalność - Docker ułatwia skalowanie aplikacji zarówno w pionie (większa moc obliczeniowa) jak i w poziomie (więcej instancji aplikacji).
Jak działa Docker?
Docker używa technologii kontenerów, które wykorzystują wirtualizację na poziomie systemu operacyjnego, aby uruchamiać wiele izolowanych aplikacji na jednej maszynie fizycznej. Kontenery są lekkie, ponieważ współdzielą jądro systemu operacyjnego hosta, co różni je od tradycyjnych maszyn wirtualnych, które wymagają pełnych systemów operacyjnych.
3. Zalety używania Docker'a
Docker zrewolucjonizował sposób, w jaki tworzymy, wdrażamy i zarządzamy aplikacjami, oferując przenośność, skalowalność i wydajność, które wcześniej były trudne do osiągnięcia. Dzięki Dockerowi programiści mogą skupić się na pisaniu kodu, a nie na zarządzaniu infrastrukturą. Do jego głównych zalet możemy zaliczyć:
- Szybkie Wdrażanie - Dzięki Dockerowi aplikacje mogą być szybko pakowane i uruchamiane w różnych środowiskach, co skraca czas wdrażania.
- Zarządzanie zależnościami - Docker zapewnia, że wszystkie zależności aplikacji są zawarte w kontenerze, co eliminuje problemy związane z różnicami w środowiskach.
- Wydajności - Kontenery Docker'a w porównaniu do maszyn wirtualnych są lekkie i wydajne z uwagi na fakt, że wykorzystują Kernel Hosta.
- Lepsze wykorzystanie zasobów - Kontenery są bardziej efektywne pod względem zasobów niż tradycyjne maszyny wirtualne, co pozwala na lepsze wykorzystanie dostępnej mocy obliczeniowej.
Docker Podstawowe Pojęcia
1. Czym to jest Obraz (Image) Docker?
Sztywny szablon, który zawiera wszystko, co jest potrzebne do uruchomienia aplikacji: kod, środowisko wykonawcze, biblioteki i narzędzia systemowe. Obrazy są wersjonowane i mogą być pobierane z repozytoriów takich jak Docker Hub czy Github Container Registry.Pierwszym etapem uruchamiania aplikacji w Dockerze jest tworzenie lub pobieranie obrazu.
2. Czym jest Kontener (Container) Docker?
Kontener to uruchomiony instancja obrazu Dockera. Jest to izolowane środowisko, które może być uruchamiane, zatrzymywane, kopiowane i usuwane. Każdy kontener jest niezależną aplikacją. Co ważne kontenery Dockera nie przechowują stanów aplikacji (np. baz danych). Jeśli usuniesz konkretny kontener który nie posiada Volumenów, to stracisz wszystkie dane z kontenera.
3. Czym jest Volumen (Volume) Docker?
Volumen Docker (ang. Docker Volume) to mechanizm używany do trwałego przechowywania danych generowanych i używanych przez kontenery Dockera. Volumeny są zarządzane przez Dockera i umożliwiają oddzielenie danych od cyklu życia kontenera. Dzięki temu dane mogą być zachowane nawet po usunięciu kontenera, co jest kluczowe dla trwałości i niezawodności aplikacji.
Wyróżniamy 3 rodzaje Volumenów:
- Volumeny zarządzane przez Docker (Managed Volumes)
Są to volumeny tworzone i zarządzane przez Dockera. Są one przechowywane w specjalnym miejscu na systemie plików hosta
(najczęściej w katalogu /var/lib/docker/volumes). - Bind Mounts
Używając bind mounts użytkownik ręcznie określa lokalizację na systemie plików hosta, która ma być udostępniona do kontenera. Umożliwia to dostęp do plików i katalogów hosta z poziomu kontenera. - TMPFS Mounts
Są to wolumeny tworzone w pamięci RAM. Są one bardzo szybkie, ale nie trwałe. Dane w tmpfs mounts są tracone po ponownym uruchomieniu kontenera lub systemu.
4. Czym jest Dockerfile?
Plik tekstowy zawierający zestaw instrukcji, które Docker używa do zbudowania obrazu. Instrukcje te określają, jakie bazy danych, biblioteki i ustawienia konfiguracyjne mają być zawarte w obrazie. Jest to swego rodzaju "Przepis na Obraz", stworzony przez Developera aplikacji.
5. Czym jest Docker Hub?
Publiczne repozytorium, gdzie można przechowywać i udostępniać obrazy Dockera. Użytkownicy mogą pobierać gotowe obrazy lub przesyłać własne. Darmowa wersja niestety nie pozwala na składowanie prywatnych obrazów w odróżnieniu od Github Container Registry.
Jak zainstalować Docker'a?
Zanim rozpoczniesz instalację platformy Docker
W zależności od posiadanego systemu operacyjnego instalacja platformy Docker wymaga innych kroków oraz elementów składowych. Dla przykładu, w systemie Linux wymagany jest tylko Docker Engine, natomiast na Windowsach wymagane jest również doinstalowanie Docker Desktop.
Szczegóły dotyczące instalacji środowiska Docker znajdziesz w linku poniżej.
Jak zainstalować Docker na Ubuntu?
Poniżej znajduje się przykładowa isntalacja platformy Docker na Ubuntu.
Odinstaluj stare wersje Docker'a
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
Dodaj oficjalne klucze GPG Docker'a
sudo apt-get updatesudo apt-get install ca-certificates curlsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.asc
Dodaj Repozytorium Docker do źródeł apt
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt-get update
Instalacja Docker'a
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Zweryfikuj poprawność instalacji
sudo docker run hello-world
Powyższa komenda pobiera obraz Hello-World a nastepnie go uruchamia. Powinieneś zobaczyć pozytywny output z aplikacji jeśli instalacja przebiegła prawidłowo.
Podstawowe Komendy Docker
Docker Cheat Sheet
Poniżej znajdują się podstawowe komendy, którę pozwolą Ci na niemalże całkowitą obsłógę Docker'a
Komendy Systemowe Docker
docker --help Wyświetla instrukcjędocker version Wyświetla wesję Docker'adocker info Wyświetla informacje o instalacji Docker'a
Zarządzanie Obrazami Docker
docker pull [nazwa_obrazu] Pobiera obraz z repozytorium Docker Hubdocker images -a Pokaż wszystkie dostępne obrazy w systemiedocker build . -t [nazwa_obrazu:tag] Zbuduj obraz i nadaj mu nazwę oraz tagdocker push [repozytorium/nazwa_obrazu:tag] Prześlij obraz do wybranego rezpoytoriumdocker rmi [id_obrazu] Usuń obraz z systemu
Zarządzanie Kontenerami Docker
docker run [nazwa_obrazu] Uruchamia nowy kontener z określonego obrazu.docker run [nazwa_obrazu] -d Uruchamia nowy kontener z określonego obrazu. (Tryb detached)docker ps Wyświetla listę uruchomionych kontenerówdocker ps -a Wyświetla listę wszystkich kontenerówdocker stop [id_kontenera] Zatrzymaj Kontenerdocker rm [id_kontenera] Usuń Kontenerdocker exec -it [id_kontenera] /bin/bash Uruchomienie powłoki systemowej Konteneradocker exec -it [id_kontenera] /bin/sh Uruchomienie powłoki systemowej Kontenera (środowisko bez Bash'a)
Jak bezpiecznie skonfigurować obraz Docker'a?
Dlaczego bezpieczna konfiguracja obrazu Docker jest tak ważna?
Bezpieczna konfiguracja obrazu Docker jest kluczowa z kilku powodów, które mają bezpośredni wpływ na integralność, poufność i dostępność aplikacji oraz danych w niej zawartych. Oto najważniejsze powody, dla których warto dbać o bezpieczeństwo obrazów Docker:
- Ochrona przed hakerami
Obrazy Docker nie różnią się w obsłudze w żaden sposób od zwykłych aplikacji. Mogą być one narażone na różne typy ataków, takie jak złośliwe oprogramowanie, ataki typu man-in-the-middle czy wykorzystanie luk w zabezpieczeniach systemów operacyjnych i aplikacji. Bezpieczna konfiguracja minimalizuje ryzyko takich ataków, zapewniając aktualne i sprawdzone wersje oprogramowania. - Izolacja aplikacji
Głównym benefitem korzystania z technologii Docker jest izolacja aplikacji. Kontenery Docker mają na celu izolowanie aplikacji od systemu hosta oraz innych kontenerów. Niewłaściwie skonfigurowane obrazy mogą prowadzić do wycieków danych między kontenerami lub pozwolić na eskalację uprawnień na hosta, co może zagrozić całemu systemowi, a w skrajnych wypadkach nawet klastrowi. - Zapewnienie Integralności Danych
Dane przechowywane i przetwarzane przez aplikacje muszą być chronione przed nieautoryzowanym dostępem i modyfikacjami. Bezpieczne konfiguracje obrazów pomagają zapobiegać naruszeniom danych i zapewniają, że dane pozostaną nienaruszone. - Minimalizacja powierzchni ataku
Minimalizacja obrazu Docker polega na usunięciu niepotrzebnych pakietów i zależności, co zmniejsza powierzchnię ataku. Im mniej komponentów w obrazie, tym mniejsza szansa, że jakiś z nich będzie miał luki w zabezpieczeniach. Zawsze staraj się opierać swój obraz produkcyjny na minimalnych obrazach systemowych. - Zgodność z przepisami i regulacjami
Wiele branż podlega rygorystycznym przepisom dotyczącym ochrony danych i prywatności, takim jak RODO czy HIPAA. Bezpieczna konfiguracja obrazów Docker pomaga w spełnianiu tych wymagań, co jest kluczowe dla uniknięcia kar finansowych i utraty reputacji. - Ułatwienie zarządzania i skalowalności
Bezpieczne obrazy są łatwiejsze w utrzymaniu i monitorowaniu. Automatyzacja aktualizacji, patchowania oraz audytów bezpieczeństwa jest prostsza, co umożliwia efektywne skalowanie aplikacji w środowiskach produkcyjnych. Warto również wykrozystywać wszelkiego rodzaju testy automatyczne w naszym CI/CD z poziomu samego Docker'a w celu wykluczenia wszelkich niedociągnięć.
Praktyki tworzenia bezpiecznych obrazów Docker
Przejdzmy teraz do podstawowych i minimalnych praktych zabezpieczania aplikacji hosotwanych w środowisku Docker. Implementacja poniższych rozwiązań powinna w dużym stopniu ograniczyć wektory ataków na naszą aplikację. Należy pamiętać, że poniższe kroki tyczą się tylko bezpieczeństwa obrazu Docker a nie całej aplikacji. W celu maksymalizacji bezpieczeństwa naszych systemów warto wykorzystać narzędzia monitorujące oraz proxy typu WAF(Web Application Firewall), które autoamtycznie będą wycinały znane im ataki.
Jaki WAF wybrać?
W zależności od aplikacji którą chcesz hostować istnieje wiele otwarto źródłowych, jak i komercyjnych rozwiązań typu Web Applcation Firewall. Najważniejsze jest dobrać odpowiednie narzędzie do danej aplikacji. Dla przykładu aplikacje oparte o PHP będą miały inne wektory ataków niż te oparte na Node.js. Do hostowania np. Wordpress'a warto będzie rozwazyć Modsecurity WAF (via Nginx), natomiast do aplikacji typu Next.js warto rozważyć wykorzystanie Arcjet (via NPM). Oczywiscie nic nie stoi na przeszkodzie w użyciu kilku WAF'ów naraz, ale nieodpowiedni jego dobór może prowadzić do wielu false-positive.
- Używanie oficjalnych i zaufanych źródeł
Korzystaj tylko z oficjalnych obrazów dostępnych na Docker Hub lub innych zaufanych rejestrach. Oficjalne obrazy są regularnie aktualizowane i sprawdzane pod kątem luk w zabezpieczeniach. Pamiętaj również aby w samej swojej aplikacji korzystać z oficjalnych pakietów i bibliotek. - Aktualizacja oprogramowania
Regularnie aktualizuj wszystkie biblioteki i obrazy systemów operacyjny w Docker. Upewnij się, że obrazy są odbudowywane z najnowszymi wersjami pakietów i poprawkami bezpieczeństwa. Staraj się dokonywać te operacje w miarę regularnie. - Minimalizacja obrazu
Twórz obrazy zawierające tylko niezbędne komponenty do uruchomienia aplikacji. Korzystaj z lekkich bazowych systemów operacyjnych, takich jak np. Alpine Linux, czy wersje Slim. Pamiętaj, że przed doborem obrazu możesz zweryfikować jego bezpieczeńśtwo w Docer Hub. Każdy obraz posiada swoją włąsną bazę podatności o której możesz przeczytać na podstronie danego wydawcy. - Zarządzanie tajnymi danymi
Obrazy Docker'a umożliwiają podgląd ich "deploymentu". Unikaj umieszczania tajnych danych, takich jak hasła, klucze API czy certyfikaty, bezpośrednio w obrazie Docker. Używaj zmiennych środowiskowych lub narzędzi do zarządzania sekretami, takich jak Docker Secrets. - Ustawienie odpowiednich uprawnień - Blokada Roota
Stosuj polityki bezpieczeństwa, takie jak SELinux lub AppArmor, aby dodatkowo zabezpieczyć kontenery i ograniczyć ich dostęp do zasobów systemowych. - Skonfigurowanie odpowiednich polityk bezpieczeństwa
Bezpieczne obrazy są łatwiejsze w utrzymaniu i monitorowaniu. Automatyzacja aktualizacji, patchowania oraz audytów bezpieczeństwa jest prostsza, co umożliwia efektywne skalowanie aplikacji w środowiskach produkcyjnych. Warto również wykrozystywać wszelkiego rodzaju testy automatyczne w naszym CI/CD z poziomu samego Docker'a w celu wykluczenia wszelkich niedociągnięć. - Regularne audyty bezpieczeństwa
Regularnie przeprowadzaj manualne lub autoamtyczne audyty bezpieczeństwa swoich obrazów Docker, aby wykrywać i naprawiać potencjalne luki w zabezpieczeniach. Korzystaj z narzędzi do skanowania bezpieczeństwa, takich jak Docker Bench for Security czy Docker Scout.
Podsumowanie
Bezpieczna konfiguracja obrazu Docker jest kluczowa dla ochrony aplikacji i danych przed różnorodnymi zagrożeniami. Dbałość o bezpieczeństwo pozwala nie tylko uniknąć problemów z naruszeniami danych, ale także zapewnia stabilność i niezawodność aplikacji w środowiskach produkcyjnych. Poprzez stosowanie dobrych praktyk, takich jak minimalizacja obrazów, regularne aktualizacje, zarządzanie tajnymi danymi oraz audyty bezpieczeństwa, można znacząco zmniejszyć ryzyko związane z wykorzystaniem technologii Docker.
Jak stworzyć swój pierwszy bezpieczny Dockerfile?
1. Struktura pliku Dockerfile
Plik Dockerfile to skrypt zawierający zestaw instrukcji i poleceń, które Docker używa do budowania obrazu. Każda instrukcja w Dockerfile wykonuje określoną operację, taką jak instalacja pakietu, ustawienie zmiennej środowiskowej lub skopiowanie plików. Poniżej szczegółowy opis podstawowej strutkury Dockerfile.

Powyższe informacje prezentują minimalną wiedzę konieczną do utworzenia swojego pierwszego własnego obrazu Docker. Oczywiście sam plik Dockerfile przyjmuje zdecydowanie więcej instrukcji oraz opcji które można znaleźć w dokumentacji Docker'a.
Dockerfile w skrócie...
Wyobraź sobie, że za każdym razem kiedy chcesz dokonać deploymentu aplikacji na nowym serwerze musisz wykonać szereg czynności mający na celu przygotowanie środowiska dla Twojej aplikacji. Musisz w pierwszej kolejności pobrać potrzebne pliki, nastepnie zainstalować biblioteki, skonfigurować bazy danych a nastepnie uruchomić aplikację tak aby nasłuchiwała na danym porcie.
Wykonywanie tych czynności ręcznie jest monotonnym i mało rozwijającym zajęciem, jako że w kółko powtarzamy te same czynności. Z pomocą przychodzi nam Docker, który wykona te wszystkie operacje za nas.
Potraktuj plik Dockerfile jako instrukcję dla samego siebie w której krok po kroku wykonujesz wszystkie czynnosci mające na celu uruchomienie Twojej aplikacji. Jeśli w toku deploymentu musisz wykonać jakąś czynność to powinna być ona również zawarta w pliku Dockerfile.
Poprawnie skonstruowany plik Dockerfile odwdzięczy Ci się czasem który byś musiał poświęcić na jednorazowy samodzielny deployment aplikacji. Ponadto Twoja aplikacja stanie się bajecznie prosta do przenoszenia pomiędzy serwerami.
2. Jak zbudować obraz z pliku Dockerfile?
W celu utworzenia obrazu z pliku Dockerfile należy wykonać następującą komendę (Terminal musi znajdować się w katalogu z plikiem Dockerfile)
docker build . -t image-name:tagEXAMPLE docker build . -t jakubwojtysiak.online:v1.0
3. Jak uruchomić obraz Docker z CMD?
W celu uruchomienia wcześniej utworzonego obrazu z pliku Dockerfile należy wykonać następującą komendę
docker run -p IP_ADDRESS:LOCAL_BROADCASTING_PORT:OPENED_CONTAINER_PORT/PROTOCOL IMG_IDEXAMPLE docker run -p 127.0.0.1:8080:80/tcp
Powyższa komenda uruchamia kontener Docker w naszej lokalnej maszynie na porcie 80. Aplikacja w kontenerze nasłuchuje na porcie 8080. Dokonano mapowania portu kontenera 8080 na port lokalny 80.
Jeśli wszystko przebiegło pomyślnie twoja aplikacja powinna być dostepna pod adresem 127.0.0.1:80 lub localhost:80.
Czy muszę wskazywać port 80 w URL?
Aplikacje Webowe z natury nasłuchują na portach 80 oraz 443. Jeśli dokonasz powyższego mapowania to wystarczy że w pasku URL przeglądarki wpiszesz tylko 127.0.0.1 lub localhost a przeglądarka autoamtycznie przekieruje Cię na port 80.
Dzieje się tak ponieważ wszystkie przeglądarki automatycznie łączą klienta z portem 80 a następnie z portem 443 jeśli dostępny jest certyfikat SSL.