Wprowadzenie do Docker Compose

Moduł Docker Compose przeznaczony do uruchamiania zestawu kontenerów w ramach jednego konkretnego projektu czy aplikacji. Innymi słowy, zestaw kilku kontenerów, które są niezbędne razem aby dany usługa/aplikacja działała w pełni. Na przykład, do działania serwisu internetowego potrzeby jest kontener z front-endem, aby użytkownik widział stronę, kontener z bazą danych, aby dane były odpowiednio przechowywane i kontener z back-endem, gdzie dzieje się cała magia aplikacji. Oczywiście często występuję więcej takich elementów-kontenerów wspomagających i składających się działanie serwisu/aplikacji. Im większa i bardziej wszechstronne aplikacja tym więcej dodatkowych kontenerów pojawia się w jej projekcie. 


W przypadku Docker Compose zmienia nam się sposób w jaki powołujemy do życia kontenery. Nie wykonujemy już złożonych poleceń w linii poleceń, tylko przygotowujemy plik w formacie YAML, w którym określamy jakie kontenery z jakimi parametrami mają być powołane do życia, a to też wszystko w odpowiedniej składni. 

Docker compose też bardzo dobrze sprawdza się nawet przy uruchamianiu pojedynczych kontenerów, a szczególnie tych z wieloma parametrami, dzięki czemu mamy czytelny obraz wszystkich opcji w kontenerze. 

Można zaryzykować stwierdzenie że użycie Docker Compose to już pewna forma orkiestracji kontenerów a na pewno ich automatyzacja, ponieważ zwykle jednym poleceniem powołujemy do życia czy zmienimy wiele obiektów na raz.

Docker Compose pod spodem korzysta z docker API.

Docker Compose na postawie opisu projektu w pliku YAML ustawiania:

  • kontenery 
  • zmienne
  • wolumeny
  • sieci

Docker compose pozwala definiować sieci, wolumeny  zależności między kontenerami i wszystko to co jest wymagane dla projektu. Pozwala to  szybko postawić pełne środowisko dla developera czy testera, choć i na produkcji takie rozwiązania też się sprawdzają. 

Jako przykład tu, mamy nowego testera, który dołącza do naszego zespołu  i aby postawił sobie nowe środowisko aplikacji na swojej maszynie  wystarczą dwa polecenia i już może zacząć swoją prace nad projektem. 

git clone <link do naszego repozytorium z aplikacja>
docker compose up

To zdecydowanie ułatwia pracę w zespołach programistycznych. 

Przykład pliku docker-compose

Weźmy na ten przykład jeden kontener Portainera z kilkoma parametrami.
W przypadku wykonania go z poziomu linii poleceń będzie wyglądać tak:

docker run -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data --name portainer -p 9000:9000 portainer/portainer-ce:alpine  -H unix:///var/run/docker.sock

Nie jest może to może najbardziej skomplikowany przykład z wieloma parametrami ale nawet tak prosty docker run tez już wymaga chwili czasu na mala analizę, co i jak tu jest uruchamiane.

Z kolei ten sam przykład Portianera w przypadku Docker Compose może wyglądać tak:

services:
  portainer:
	image: portainer/portainer-ce:alpine
	container_name: portainer
	command: -H unix:///var/run/docker.sock
	ports:
  	- "9000:9000"
	volumes:
  	- "/var/run/docker.sock:/var/run/docker.sock"
  	- "portainer_data:/data"
	restart: always

volumes:
  portainer_data:

Według mnie, to już jest bardziej czytelne jeśli chodzi o składnie bo oko ludzkie już szybciej już wyłapuje jaki atrybut jaka wartosc ma ustawioną.

W Docker Compose pod pojęciem “service” kryje jeden kontener, który pełni jakąś rolę w naszym projekcie. Dlatego w pliku mamy listę serwisów z ich ustawieniami. 

A teraz sprawdźmy przykład, składający  się z kilku kontenerów, czyli taki w jakim najlepiej pracuje się z docker compose. 

services:
  db:
	image: mariadb:10.6.4-focal
	command: '--default-authentication-plugin=mysql_native_password'
	volumes:
  	- db_data:/var/lib/mysql
	restart: always
	environment:
  	- MYSQL_ROOT_PASSWORD=somewordpress
  	- MYSQL_DATABASE=wordpress
  	- MYSQL_USER=wordpress
  	- MYSQL_PASSWORD=wordpress
	expose:
  	- 3306
  	- 33060
  wordpress:
	image: wordpress:latest
	ports:
  	- 80:80
	restart: always
	environment:
  	- WORDPRESS_DB_HOST=db
  	- WORDPRESS_DB_USER=wordpress
  	- WORDPRESS_DB_PASSWORD=wordpress
  	- WORDPRESS_DB_NAME=wordpress
volumes:
  db_data:

Tu już mamy dwa kontenery czyli serwisy. Dodatkowo kilka niezbędnych zmiennych środowiskowych i jeszcze deklaracje wolumenu. 

Nie trzeba dodawać, że powyższy przykład z wordpressem i tylko dwoma kontenerami, to w formie docker run z wiersza poleceń byłby wielolinijkowym złożonym poleceniem, przez co na pewno mało czytelny. Dlatego Docker Compose jest taki fajny bo gdy kontenery nam się komplikują, Docker Compose wszystko upraszcza.

Nazwa serwisu/ jest też używana w sieci dockerowej jako nazwa DNS danego kontenera wiec możemy się do niej odnosić sieciowo jak w powyższym przykładzie jest to WORDPRESS_DB_HOST=db

Plik z definicją naszych serwisów powinien być zapisany w pliku compose.yml lub compose.yaml w katalogu. Gdzie nazwa jest jego istotna ponieważ Docker Compose przyjmuje nazwę tegoż katalogu jako domyślną nazwę naszego projektu.

Obsługa Docker Compose

Do obsługi plików YAML używamy narzędzia docker compose z linii poleceń

Do uruchomienia projektu czyli uruchomieni zdefiniowanych kontenerów i innych obiektów z pliku compose służy polecenie

docker compose up

Oczywiście wykonywane w katalogi gdzie znajduje się plik. Powyższy przykład spowoduje uruchomienie projektu i wypisanie wyników (output) w terminalu

Jednak, wydaje mi się, że częściej wykorzystywanym poleceniem będzie te gdzie uruchomienie projektu jest trybie detach czyli we tle:

docker compose up -d

Do zatrzymania całego projektu, służy polecenie:

docker compose down

To polecenie powoduje usunięcie kontenerów i sieci stworzonych na podstawie pliku compose.yml ale pozostawia wolumeny.

Aby zatrzymać projekt, usunąć kontenery, sieci i wolumeny należy wydać polecenie 

docker compose down -v

 Wiadomo, te polecenia używamy z rozwagą by przez przypadek nie usnąć danych w wolumenach,  które chcemy zachować 

Aby tylko zatrzymać wszystkie kontenery w projekcie, bez usuwania go:

docker compose stop

Tak samo, aby wystartować je ponownie:

docker compose start

Możemy też zatrzymać/wystartować pojedynczy kontener podając jego nazwę serwisu po poleceniu. 

Aby sprowadzić procesy pracujące w danym projekcie wystarczy polecenie

docker compose top

Wszystkie polecenia zobaczymy poleceniem docker compose -help

Opcjonalnie można wskazać też plik który znajduje się w innym miejscu dodając parametr -f i ścieżkę do nazwy pliku 

docker compose up -f /sciezka/do/innej/lokalizacji/compose.yaml

W 2022 roku wyszła wersja V2. Przebudowano całkowicie ten moduł Dockera. Czego efektem jest między innymi to że zmieniła się składnia użycia. Zamiast polecenia docker-compose (z myślnikiem pomiędzy) używamy teraz docker compose (ze spacją pomiędzy) przez co stare projekty zbudowane z użyciem frazy docker-compose mogą się nie uruchomić z naszą aktualną wersja Docker Compose. Najłatwiejszym rozwiązaniem problemu będzie tu po prostu usunięcie myślnika z pomiędzy wyrazów i zastąpienie go spacją.

Tags: