• Post last modified:14/05/2020
  • Post Category:FrontOps
  • Post Comments:4 komentarze

Dzisiejszy wpis zaczyna krótką serię artykułów na temat niezwykle popularnego obecnie Dockera. Technologia ta najczęściej kojarzy nam się z aplikacjami back end-owymi, jednakże może okazać się niezwykle przydatna również w przypadku front end-u. Omówimy sobie dzisiaj czym jest Docker, jak zacząć z niego korzystać i uruchomimy nasz pierwszy kontener. W kolejnych wpisach skupimy się już na dokładniejszym omówieniu koncepcji obrazów oraz kontenerów a także sami spróbujemy użyć Dockera na przykładzie aplikacji składającej się na froncie z React-owego frameworka NextJS oraz bardzo prostego API napisanego przy użyciu Express. Zarówno front end i jak i back end tej aplikacji będzie działał w swoim własnym kontenerze. Zacznijmy wprowadzenie od odpowiedzi na podstawowe pytanie – czym jest docker?

Dwa słowa wstępu

Zdaję sobie sprawę, że jeżeli czytasz ten artykuł to istnieje spora szansa na to, że jesteś programistą front end-owym, który chce dość szybko i sprawnie nauczyć się Dockera na tyle dobrze, żeby radzić sobie z nim w codziennej pracy bądź może w jakimś swoim pobocznym projekcie. Być może chcesz sobie tylko szybko odświeżyć wiedzę. Albo, co jeszcze lepiej, postanowiłeś sam z siebie zapoznać się z nową technologią w ramach samorozwoju. Mając to na uwadze postaram się, aby wszystkie wpisy były proste, klarowne, łatwe do zrozumienia i z dużą ilością odnośników do zewnętrznych materiałów w których będzie można zagłębić się w detale omawianych tematów.

Czym jest Docker?

Docker jest platformą, dzięki której możemy rozwijać oraz wdrażać nasze aplikacje w postaci samowystarczalnych kontenerów. Kontenery (omówimy je dokładniej nieco później) są odizolowanym środowiskiem uruchomieniowym dla naszej aplikacji. Można porównać je do maszyn wirtualnych uruchamianych na Windowsie np. za pomocą Hyper-V. Dzięki temu możemy na jednym fizycznym sprzęcie uruchomić Windowsa oraz Linuxa. Jednak każda maszyna wirtualna posiada własny system operacyjny. Tym samym uruchomienie kilku maszyn oznacza uruchomienie kilku systemów operacyjnych, co może być dużym obciążeniem dla jednego komputera. Do tego najczęściej nowo uruchomiony system należy odpowiednio skonfigurować i zainstalować wszystkie potrzebne nam biblioteki w odpowiednich wersjach i konfiguracjach. Tak naprawdę interesujące i przydatne dla nas jest to wszystko co działa wewnątrz systemu operacyjnego a nie sam OS.

Docker i kontenery znacznie upraszczają cały ten proces. Zamiast instalować hipervisora i całe systemy operacyjne uruchamiamy jedynie to co powinno działać wewnątrz tego systemu (czyli np. NodeJS bądź MongoDB). Jedynym systemem operacyjnym jest wtedy OS działający na naszym komputerze-hoście. Docker jest odpowiedzialny za to, żeby podkraść z naszego fizycznego sprzętu nieco zasobów (tj. miejsce na dysku twardym, RAM, usługi sieciowe, itp.) i przeznaczyć je dla pojedynczego kontenera. A co najważniejsze – to co zostanie przydzielone kontenerowi należy tylko do tego kontenera. Nawet host nie ma dostępu do zasobów z których korzysta kontener. Wszystkie kontenery są odizolowane zarówno od siebie jak i od naszego systemu operacyjnego.

Co i jak powinno być uruchomione wewnątrz kontenera jest określone przez plik nazywany Dockerfile. To tam znajdują się informacje jakie wersje biblioteki powinny być zainstalowane, jak powinny zostać skonfigurowane, w jakiej kolejności uruchomione, itp. Można trochę o nim myśleć jak o pliku package.json, ale dla Dockera.

Tyle na razie powinno nam wystarczyć, żeby uruchomić Dockera i odpalić nasz pierwszy kontener. Mając już żywy organizm dużo łatwiej będzie zagłębiać się w kolejne tematy. Jeżeli jednak ktoś czuje niedosyt wiedzy – może poświęcić jeszcze kilka minut na ten oto artykuł na stronie MS.

Instalacja

Instalacja Dockera na naszym komputerze w większości przypadków nie różni się bardzo od instalacji standardowych programów (Install -> Next -> Next -> Finish ). Dockera możemy zainstalować na Windowsie, MacOS oraz Linuxie. W przypadku Windowsa oraz macOS zainstalujemy dwa główne składnikiDocker Client oraz Docker Server (nazywany również jako Docker Daemon).

docker client oraz docker server

Docker Client jest narzędziem w którym to będziemy wpisywać wszelkie obsługiwane komendy w wybranym przez nas terminalu (np. CMD, Powershell, itp.). Sam client nie potrafi nic więcej oprócz komunikacji z Docker Server. To server jest odpowiedzialny za wszystkie kluczowe operacje, czyli np. generowanie obrazów, uruchamianie kontenerów, itp.

Instalacja na Windows / macOS

Pracując na macOS bądź Windowsie w wersji Professional lub Enterprise możemy skorzystać z darmowej i bardzo prostej w instalacji wersji – Docker Desktop. W przypadku macOS oprogramowanie możemy pobrać z tej strony i zainstalować korzystając z gotowej instrukcji.

Windows-owy plik instalacyjny jest do znalezienie pod tym linkiem. Po pobraniu instalujemy tak jak każdą standardową aplikację. Jedna rzecz warta odnotowania – podczas instalacji upewnijmy się, że opcja „Use windows containers instead of Linux containers” nie jest zaznaczona. Po instalacji restartujemy system (instalator zresztą sam się o to upomni) i jesteśmy gotowi do pracy. Docker potrzebuje ok 1-2 minut, aby się uruchomić. Znajdziemy wtedy w naszym zasobniku nową ikonkę:

ikonka dockera
Ikonka uruchomionego Dockera

Instalacja na Windows Home

Użytkownicy Windows Home niestety nie będą mogli zainstalować Docker Desktop for Windows, ponieważ wymaga on obecności Hyper-V w systemie a ten jest obecny tylko w wersjach Professional and Enterprise. W takim wypadku należy zainstalować Docker Toolbox. Toolbox zainstaluje nam VirtualBox, który zastąpi Hyper-V. W niektórych przypadkach wymagane będzie dodatkowo uruchomienie wirtualizacji w BIOSie, ale zależy to już od producenta naszego sprzętu.

Instalacja na Linuxie

W przypadku instalacji na Linuxie możemy skorzystać z oficjalnych poradników ze strony Dockera. Nie będziemy tutaj zgłębiać tego tematu. Poradniki dostępne są dla systemów Ubuntu, Fedora, Debian oraz CentOS.

Pierwsze uruchomienie

Po zakończeniu instalacji możemy upewnić się czy wszystko przebiegło bez błędów uruchamiając w terminalu komendę docker version. Zobaczymy wtedy, iż faktycznie na naszym sprzęcie działają dwa narzędzia – client oraz server:

Widok wiersza poleceń po wykonaniu polecenia docker version

Jako ciekawostkę można wskazać tutaj jedną wartość z sekcji Server – pole OS/Arch. Pisząc ten artykuł i uruchamiając kolejne komendy pracuję na Windowsie 10. Widać to dokładnie w sekcji Client -> OS/Arch. Dockerowy Server z kolei jest uruchomiony na Linuxie. Instalując aplikację Docker Desktop for Windows instalujemy również w pakiecie u siebie wirtualną maszynę z Linuxem. Za każdym razem gdy uruchamiam Dockera to z technicznego punktu widzenia w tle uruchamia się również wspomniana już maszyna wirtualna. To wewnątrz tej maszyny będziemy tworzyć wszystkie przyszłe kontenery.

Docker Image

Gdy upewnimy się, że instalacja Dockera przebiegła pomyślnie możemy spróbować uruchomić kontener. Tutaj po raz pierwszy pojawi się termin Docker Image.

Wiemy już, że kontenery uruchamiają się na naszym systemie operacyjnym i posiadają w sobie jakiś uruchomiony program bądź proces. Obraz w terminologii Dockera odnosi się do pliku, który posiada w sobie wszystkie pliki, biblioteki, skrypty i wszystko co jest wymagane do poprawnego uruchomienia programu. Obraz jest plikiem tylko do odczytu, nie możemy bezpośrednio modyfikować znajdujących się wewnątrz niego plików. Docker Server potrafi odczytać taki obraz i korzystając z niego uruchomić kontener, który będzie działającą instancją obrazu. Sposób w jaki to się odbywa omówimy dokładniej w następnym wpisie.

Wiemy więc już, że kontenery są działającymi instancjami obrazów, uruchomionymi na naszym lokalnym systemie operacyjnym:

Tworzenie kontenerów z obrazu. Każdy kontener ma uruchomioną dokładnie tą samą aplikację

Pytanie które teraz może się pojawić – skąd wziąć te obrazy? Oczywiście możemy (i niedługo będziemy) tworzyć je samodzielnie, jednak niemal zawsze będą bazowały one na jakimś innym, oficjalnym obrazie. Docker posiada darmowe repozytorium obrazów z którego możemy skorzystać – Docker Hub. Można to luźno porównać do tego czym jest npm w świecie NodeJS / JavaScript. W repozytorium tym znajdziemy obrazy np. NodeJS czy MongoDB a także czyste systemy operacyjne takie jak Ubuntu dzięki czemu możemy od razu zacząć z nich korzystać.

Hello World

Teraz jednak skorzystamy z najbardziej podstawowego obrazu – Hello World. Obraz ten zawiera program, którego cała funkcjonalność to wyświetlenie nam wiadomości w terminalu (wierszu poleceń). Uruchomi on się oczywiście w swoim kontenerze.

Do uruchomienia kontenera bezpośrednio z obrazu pochodzącego z Docker Hub możemy skorzystać z komendy docker run image-name. W przypadku obrazu hello-world powinniśmy otrzymać następujący rezultat:

Uruchomienie kontenera z obrazu hello-world

Dwa słowa wyjaśnienia co teraz odbyło się za kulisami. Po uruchomieniu ww. komendy Docker sprawdza z jakiego obrazu chcemy uruchomić nowy kontener. Następnie sprawdzone zostaje, czy być może w naszym lokalnym cache nie mamy już zapisanego tego obrazu. Jako że uruchamiamy Dockera po raz pierwszy nie będziemy go posiadali. Widzimy to w logach terminala jako wiersz Unable to find image 'hello-world:latest' locally. W takim wypadku musimy wyjść poza naszą lokalną maszynę i sprawdzić czy obraz jest dostępny w repozytorium Docker Hub. Jeżeli obraz zostanie tam znaleziony to zostanie pobrany na nasz dysk i zapisany w cache. Dzięki temu przy kolejnym tworzeniu kontenera z tego obrazu nie będziemy musieli pobierać go z zewnątrz, tylko użyjemy wersji zapisanej lokalnie. Cały ten proces możemy przedstawić jako poniższy schemat:

Zapisywanie obrazu z Docker Hub w lokalnym cache

Posiadając już obraz na naszej maszynie Docker może utworzyć z niego kontener. Wszystko co wyświetla się od wiersza Hello from Docker!jest wynikiem działania kontenera.

Jak już wcześniej wspomniałem raz zapisany obraz nie będzie pobierany ponownie przy uruchamianiu nowego kontenera. Wykonajmy więc komendę docker run hello-world jeszcze raz:

Ponowne utworzenie kontenera z lokalnego obrazu

Tym razem mamy od razu wynik działania kontenera. Zniknęła nam informacja o pobieraniu obrazu. Został on uruchomiony z naszego lokalnego dysku twardego.

Podsumowanie

Dowiedzieliśmy się już czym jest i jak działa Docker. Wiemy również, iż wszystkie nowo tworzone kontenery są tak na prawdę lokalnie działającymi instancjami obrazów (Docker Images). Obrazy te z kolei można znaleźć i pobrać z repozytorium o nazwie Docker Hub. Każdy obraz jest plikiem tylko do odczytu i zawiera wszystkie pliki, biblioteki i tym podobne rzeczy umożliwiające kontenerowi prawidłowe działanie.

Ale czym tak naprawdę jest ten kontener? Jak stworzyć swój własny obraz? Jak sprawdzić czy mamy na komputerze jakieś uruchomione kontenery? Odpowiedź na te pytania oraz listę najważniejszych komend stosowanych w Dockerze znajdziemy w kolejnym wpisie.

Kamil Józwik

Front end developer👨‍💻 Autor małego narzędzia dla programistów - frontbook.dev oraz autor kolejnych postów na tym blogu. Ulubiony stack to React wraz z TypeScript oraz wszystko co "nowe" w tym pięknym dynamicznym front end-owym świecie 🙂

Ten post ma 4 komentarzy

  1. Marcin

    Fajnie i prosto tłumaczone. Jak często będą posty dotyczące Docker’a ?

    1. Kamil Józwik

      Wszystko zależy od obłożenia innymi projektami, ale mam nadzieję chociaż te 2 posty w tygodniu umieszczać

      1. Marcin

        Dzięki za info ! Będę śledził i uczył się z ciekawością ;D

  2. jsview.pl

    Fajnie to wygląda. Wytłumaczone akurat na ile to potrzebne by zrozumieć podstawy 🙂

Dodaj komentarz