Przewodnik po Docker Compose dla początkujących

Autor artykułu, którego tłumaczenie dzisiaj publikujemy, twierdzi, że jest on przeznaczony dla tych programistów, którzy chcą nauczyć się Docker Compose i dążą do stworzenia swojej pierwszej aplikacji kliencko-serwerowej przy użyciu Dockera. Zakłada się, że czytelnik tego materiału zna podstawy Dockera. Jeśli nie — możesz zerknąć na tego serię materiałów na tego publikację, w której podstawy Dockera omówione są wraz z podstawami Kubernetes, oraz na tego artykuł dla początkujących.

Przewodnik po Docker Compose dla początkujących

Czym jest Docker Compose?

Docker Compose to narzędzie wchodzące w skład Dockera. Służy do rozwiązywania zadań związanych z wdrażaniem projektów.

Ucząc się podstaw Dockera, mogłeś spotkać się z tworzeniem najprostszych aplikacji, działających autonomicznie, niezależnych na przykład od zewnętrznych źródeł danych lub od pewnych usług. W praktyce jednak takie aplikacje są rzadkością. Rzeczywiste projekty zazwyczaj obejmują cały zestaw współpracujących aplikacji.

Jak dowiedzieć się, czy podczas wdrażania projektu warto skorzystać z Docker Compose? W rzeczywistości to bardzo proste. Jeśli do zapewnienia funkcjonowania tego projektu używa się kilku usług, Docker Compose może okazać się pomocny. Na przykład w sytuacji, gdy tworzony jest serwis internetowy, który do wykonania uwierzytelniania użytkowników musi połączyć się z bazą danych. Taki projekt może składać się z dwóch usług — jednej, która obsługuje serwis, oraz drugiej, która odpowiada za utrzymanie bazy danych.

Technologia Docker Compose, mówiąc w uproszczeniu, pozwala za pomocą jednego polecenia uruchomić wiele usług.

Różnica między Dockerem a Docker Compose

Docker stosowany jest do zarządzania pojedynczymi kontenerami (usługami), z których składa się aplikacja.

Docker Compose używany jest do jednoczesnego zarządzania wieloma kontenerami, które wchodzą w skład aplikacji. To narzędzie oferuje te same możliwości co Docker, ale pozwala pracować z bardziej złożonymi aplikacjami.

Przewodnik po Docker Compose dla początkujących
Docker (pojedynczy kontener) i Docker Compose (wiele kontenerów)

Typowy scenariusz użycia Docker Compose

Docker Compose to w rękach doświadczonego użytkownika bardzo potężne narzędzie, które pozwala na szybkie wdrażanie aplikacji o złożonej architekturze. Teraz przyjrzymy się przykładowemu zastosowaniu Docker Compose, którego analiza pozwoli ocenić korzyści płynące z jego użycia.

Wyobraźmy sobie, że jesteś deweloperem pewnego projektu internetowego. Projekt ten obejmuje dwie witryny. Pierwsza umożliwia osobom prowadzącym działalność gospodarczą stworzenie sklepu internetowego w zaledwie kilka kliknięć. Druga jest skierowana na wsparcie klientów. Obie witryny korzystają z tej samej bazy danych.

Twój projekt staje się coraz bardziej popularny i okazuje się, że moc serwera, na którym działa, już nie wystarcza. W rezultacie postanawiasz przenieść cały projekt na inną maszynę.

Niestety, nie używałeś czegoś takiego jak Docker Compose. Dlatego będziesz musiał przenosić i rekonfigurować usługi pojedynczo, mając nadzieję, że podczas tej pracy niczego nie zapomnisz.

Jeśli jednak używasz Docker Compose, przeniesienie projektu na nowy serwer to sprawa, którą można rozwiązać wykonując kilka poleceń. Aby ukończyć przenoszenie projektu w nowe miejsce, wystarczy, że dokonasz kilku ustawień i załadujesz na nowy serwer kopię zapasową bazy danych.

Tworzenie aplikacji kliencko-serwerowej z użyciem Docker Compose

Teraz, kiedy już wiesz, w jakim celu zamierzamy wykorzystać Docker Compose, przyszedł czas na stworzenie twojej pierwszej aplikacji kliencko-serwerowej z użyciem tego narzędzia. Będzie to mała witryna internetowa (serwer) napisana w Pythonie, która potrafi zwracać plik z fragmentem tekstu. O ten plik prosi program (klient), także napisany w Pythonie. Po odebraniu pliku z serwera program wyświetla na ekranie tekst, który w nim się znajduje.

Zwróć uwagę, że zakładamy, iż znasz podstawy Docker i że masz już zainstalowaną platformę Docker.

Rozpocznijmy pracę nad projektem.

▍1. Tworzenie projektu

Aby zbudować swoją pierwszą aplikację kliencko-serwerową, proponuję zacząć od utworzenia folderu projektu. Powinien on zawierać następujące pliki i foldery:

  • Plik docker-compose.ymlTo jest plik Docker Compose, który będzie zawierał instrukcje potrzebne do uruchomienia i konfiguracji usług.
  • Folder serverBędzie zawierał pliki potrzebne do zapewnienia działania serwera.
  • Folder clientTutaj znajdą się pliki aplikacji klienckiej.

W rezultacie zawartość głównego folderu twojego projektu powinna wyglądać następująco:

.
├── client/
├── docker-compose.yml
└── server/
2 katalogi, 1 plik

▍2. Tworzenie serwera

Podczas tworzenia serwera poruszymy kilka podstawowych kwestii dotyczących Dockera.

2a. Tworzenie plików

Przejdź do folderu server i stwórz w nim następujące pliki:

  • Plik server.pyW nim znajdzie się kod serwera.
  • Plik index.htmlW tym pliku znajdzie się fragment tekstu, który ma zostać wyświetlony przez aplikację kliencką.
  • Plik DockerfileTo jest plik Docker, który będzie zawierał instrukcje potrzebne do utworzenia środowiska serwera.

Oto jak powinna wyglądać zawartość twojego folderu server/:

.
├── Dockerfile
├── index.html
└── server.py
0 katalogów, 3 pliki

2b. Edytowanie pliku Python.

Dodamy do pliku server.py następujący kod:

#!/usr/bin/env python3

# Импорт системных библиотек python.
# Эти библиотеки будут использоваться для создания веб-сервера.
# Вам не нужно устанавливать что-то особенное, эти библиотеки устанавливаются вместе с Python.

import http.server
import socketserver

# Эта переменная нужна для обработки запросов клиента к серверу.

handler = http.server.SimpleHTTPRequestHandler

# Тут мы указываем, что сервер мы хотим запустить на порте 1234. 
# Постарайтесь запомнить эти сведения, так как они нам очень пригодятся в дальнейшем, при работе с docker-compose.

with socketserver.TCPServer(("", 1234), handler) as httpd:

    # Благодаря этой команде сервер будет выполняться постоянно, ожидая запросов от клиента.

   httpd.serve_forever()

Ten kod позволяет stworzyć prosty serwer WWW. Będzie on zwracał klientom plik index.html, którego zawartość później zostanie wyświetlona na stronie internetowej.

2c. Edytowanie pliku HTML

Dodamy do pliku index.html następujący tekst:

Docker-Compose to magia!

Ten tekst zostanie przekazany klientowi.

2d. Edytowanie pliku Dockerfile

Teraz stworzymy prosty plik Dockerfile, który będzie odpowiedzialny za organizację środowiska uruchomieniowego dla serwera Python. Jako bazę dla tworzonego obrazu wykorzystamy oficjalny obraz, przeznaczony do uruchamiania programów napisanych w Pythonie. Oto zawartość Dockerfile:

# На всякий случай напоминаю, что Dockerfile всегда должен начинаться с импорта базового образа.
# Для этого используется ключевое слово 'FROM'.
# Здесь нам нужно импортировать образ python (с DockerHub).
# В результате мы, в качестве имени образа, указываем 'python', а в качестве версии - 'latest'.

FROM python:latest

# Для того чтобы запустить в контейнере код, написанный на Python, нам нужно импортировать файлы 'server.py' и 'index.html'.
# Для того чтобы это сделать, мы используем ключевое слово 'ADD'.
# Первый параметр, 'server.py', представляет собой имя файла, хранящегося на компьютере.
# Второй параметр, '/server/', это путь, по которому нужно разместить указанный файл в образе.
# Здесь мы помещаем файл в папку образа '/server/'.

ADD server.py /server/
ADD index.html /server/

# Здесь мы воспользуемся командой 'WORKDIR', возможно, новой для вас.
# Она позволяет изменить рабочую директорию образа.
# В качестве такой директории, в которой будут выполняться все команды, мы устанавливаем '/server/'.

WORKDIR /server/

Teraz zajmiemy się pracą nad klientem.

▍3. Tworzenie klienta

Tworząc część klienta naszego projektu, przypomnimy sobie pewne podstawy Dockera.

3a. Tworzenie plików

Przejdź do folderu swojego projektu client i stwórz w nim następujące pliki:

  • Plik client.pyTutaj znajdzie się kod klienta.
  • Plik DockerfileTen plik odgrywa tę samą rolę, co odpowiedni plik w folderze serwera. Mianowicie zawiera instrukcję, opisującą utworzenie środowiska dla wykonywania kodu klienckiego.

W rezultacie twój folder client/ na tym etapie pracy powinien wyglądać tak:

.
├── client.py
└── Dockerfile
0 katalogów, 2 pliki

3b. Edytowanie pliku Python.

Dodamy do pliku client.py następujący kod:

#!/usr/bin/env python3

# Импортируем системную библиотеку Python.
# Она используется для загрузки файла 'index.html' с сервера.
# Ничего особенного устанавливать не нужно, эта библиотека устанавливается вместе с Python.

import urllib.request

# Эта переменная содержит запрос к 'http://localhost:1234/'.
# Возможно, сейчас вы задаётесь вопросом о том, что такое 'http://localhost:1234'.
# localhost указывает на то, что программа работает с локальным сервером.
# 1234 - это номер порта, который вам предлагалось запомнить при настройке серверного кода.

fp = urllib.request.urlopen("http://localhost:1234/")

# 'encodedContent' соответствует закодированному ответу сервера ('index.html').
# 'decodedContent' соответствует раскодированному ответу сервера (тут будет то, что мы хотим вывести на экран).

encodedContent = fp.read()
decodedContent = encodedContent.decode("utf8")

# Выводим содержимое файла, полученного с сервера ('index.html').

print(decodedContent)

# Закрываем соединение с сервером.

fp.close()

Dzięki temu kodowi aplikacja kliencka może pobierać dane z serwera i wyświetlać je na ekranie.

3c. Edytowanie pliku Dockerfile

Podobnie jak w przypadku serwera, tworzymy dla klienta prosty Dockerfile, odpowiedzialny za utworzenie środowiska, w którym będzie działać klientowska aplikacja Python. Oto kod klienta Dockerfile:

# То же самое, что и в серверном Dockerfile.

FROM python:latest

# Импортируем 'client.py' в папку '/client/'.

ADD client.py /client/

# Устанавливаем в качестве рабочей директории '/client/'.

WORKDIR /client/

▍4. Docker Compose

Jak mogliście zauważyć, stworzyliśmy dwa różne projekty: serwer i klient. Każdy z nich ma swój własny plik Dockerfile. Jak dotąd wszystko, co się dzieje, nie wykracza poza podstawy pracy z Dockerem. Teraz przechodzimy do pracy z Docker Compose. W tym celu odwołamy się do pliku docker-compose.yml, który znajduje się w głównym folderze projektu.

Zauważcie, że tutaj nie staramy się omówić absolutnie wszystkich poleceń, które można wykorzystać w docker-compose.yml. Naszym głównym celem jest omówienie praktycznego przykładu, który da Wam podstawową wiedzę na temat Docker Compose.

Oto kod, który należy umieścić w pliku docker-compose.yml:

# Файл docker-compose должен начинаться с тега версии.
# Мы используем "3" так как это - самая свежая версия на момент написания этого кода.

version: "3"

# Следует учитывать, что docker-composes работает с сервисами.
# 1 сервис = 1 контейнер.
# Сервисом может быть клиент, сервер, сервер баз данных...
# Раздел, в котором будут описаны сервисы, начинается с 'services'.

services:

  # Как уже было сказано, мы собираемся создать клиентское и серверное приложения.
  # Это означает, что нам нужно два сервиса.
  # Первый сервис (контейнер): сервер.
  # Назвать его можно так, как нужно разработчику.
  # Понятное название сервиса помогает определить его роль.
  # Здесь мы, для именования соответствующего сервиса, используем ключевое слово 'server'.

  server:
 
    # Ключевое слово "build" позволяет задать
    # путь к файлу Dockerfile, который нужно использовать для создания образа,
    # который позволит запустить сервис.
    # Здесь 'server/' соответствует пути к папке сервера,
    # которая содержит соответствующий Dockerfile.

    build: server/

    # Команда, которую нужно запустить после создания образа.
    # Следующая команда означает запуск "python ./server.py".

    command: python ./server.py

    # Вспомните о том, что в качестве порта в 'server/server.py' указан порт 1234.
    # Если мы хотим обратиться к серверу с нашего компьютера (находясь за пределами контейнера),
    # мы должны организовать перенаправление этого порта на порт компьютера.
    # Сделать это нам поможет ключевое слово 'ports'.
    # При его использовании применяется следующая конструкция: [порт компьютера]:[порт контейнера]
    # В нашем случае нужно использовать порт компьютера 1234 и организовать его связь с портом
    # 1234 контейнера (так как именно на этот порт сервер 
    # ожидает поступления запросов).

    ports:
      - 1234:1234

  # Второй сервис (контейнер): клиент.
  # Этот сервис назван 'client'.

  client:
    # Здесь 'client/ соответствует пути к папке, которая содержит
    # файл Dockerfile для клиентской части системы.

    build: client/

    # Команда, которую нужно запустить после создания образа.
    # Следующая команда означает запуск "python ./client.py".
 
    command: python ./client.py

    # Ключевое слово 'network_mode' используется для описания типа сети.
    # Тут мы указываем то, что контейнер может обращаться к 'localhost' компьютера.

    network_mode: host

    # Ключевое слово 'depends_on' позволяет указывать, должен ли сервис,
    # прежде чем запуститься, ждать, когда будут готовы к работе другие сервисы.
    # Нам нужно, чтобы сервис 'client' дождался бы готовности к работе сервиса 'server'.
 
    depends_on:
      - server

▍5. Kompilacja projektu

Po tym, jak w docker-compose.yml wprowadzone zostały wszystkie niezbędne instrukcje, projekt należy skompilować. Ten krok naszej pracy przypomina użycie polecenia docker build, ale odpowiednie polecenie dotyczy kilku usług:

$ docker-compose build

▍6. Uruchamianie projektu

Teraz, gdy projekt został skompilowany, nadszedł czas na jego uruchomienie. Ten krok naszej pracy odpowiada kroku, na którym, przy pracy z osobnymi kontenerami, wykonuje się polecenie docker run:

$ docker-compose up

Po wykonaniu tego polecenia w terminalu powinien pojawić się tekst załadowany przez klienta z serwera: Docker-Compose to magia!.

Jak już wspomniano, serwer używa portu komputera 1234 do obsługi zapytań klienta. Dlatego, jeśli przejdziecie w przeglądarce pod adres http://localhost:1234/, na którym wyświetli się strona z tekstem Docker-Compose to magia!.

Przydatne polecenia

Przyjrzyjmy się kilku poleceniom, które mogą Wam się przydać podczas pracy z Docker Compose.

To polecenie umożliwia zatrzymywanie i usuwanie kontenerów oraz innych zasobów utworzonych przez polecenie docker-compose up:

$ docker-compose down

To polecenie wyświetla logi usług:

$ docker-compose logs -f [nazwa usługi]

Na przykład w naszym projekcie można je użyć w następujący sposób: $ docker-compose logs -f [nazwa usługi].

Dzięki temu poleceniu można wyświetlić listę kontenerów:

$ docker-compose ps

To polecenie umożliwia wykonanie polecenia w działającym kontenerze:

$ docker-compose exec [nazwa usługi] [polecenie]

Na przykład może wyglądać tak: docker-compose exec server ls.

To polecenie pozwala wyświetlić listę obrazów:

$ docker-compose images

Podsumowanie

Omówiliśmy podstawy korzystania z technologii Docker Compose, których znajomość umożliwi Ci korzystanie z tej technologii i, jeśli chcesz, rozpoczęcie jej głębszego studiowania. Oto repozytorium z kodem projektu, który rozważaliśmy tutaj.

Drodzy Czytelnicy! Czy korzystasz z Docker Compose w swoich projektach?

Przewodnik po Docker Compose dla początkujących

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster