DevOps / Software-Entwicklung

Anwendungsstacks mit Docker Compose

Schon beim Lernen der ersten Dockerbefehle, die ich im Artikel  „Docker Basics – Befehle und Life Hacks“ näher beschrieben habe, ist mir aufgefallen, dass ich immer und immer wieder die gleichen Befehle benötige. Also kam mir die Idee diese Befehle in einem Shellscript oder einer Batchdatei zu speichern, um anschließend alle Services gemeinsam starten zu können. Das ist aber genau der Punkt den Docker-Compose abnimmt und sogar um einiges erweitert. Sehen wir uns daher diesmal Docker Compose und die dazugehörigen Befehle an.

Docker Compose

Um mehrere Container, welche gemeinsam eine Anwendung bilden, zusammen starten zu können, kann man ein shell script erstellen, welches alle docker run -param1 -param2 Befehle für jeden Container enthält. Um dies aber nicht mit einem shell script machen zu müssen, wurde docker-compose entwickelt. Mit docker-compose können mehrere Docker Images konfiguriert und hintereinander gestartet werden. Somit muss nicht jeder Container mit docker run und allen Parametern gestartet werden, sondern die Container und Einstellungen werden in dem docker-compse.yml File definiert.

Docker compose wird bei der Installation von Docker mitgeliefert, sollte dies nicht der Fall sein wird hier https://docs.docker.com/compose/install/#install-compose beschrieben wie Docker Compose separat installiert werden kann.
Ein docker-compose.yml File muss immer in der ersten Zeile der verwendeten Version angegeben werden. Anschließend können die services, die networks oder die volumes definiert werden, services entspricht dabei dem docker run Befehlen, welche einen Container erstellen und starten. In der Sektion networks können Netzwerke definiert werden und mit volumes File mounts.
Nachfolgend werden die wichtigsten Elemente eines docker-compose.yml Files beschrieben. Eine komplette Liste aller Befehle findet man unter https://docs.docker.com/compose/compose-file/.

Beispiel einer docker-compose.yml für wordpress (Quelle: https://github.com/docker-library/docs/tree/master/wordpress):

In diesem Beispiel werden zwei Docker Container erstellt. Der erste mit dem Namen „wordpress“. Er basiert auf einem Image names „wordpress“. Es werden die Ports 8080 des Hostsystems auf den Post 80 des Docker Containers gemappt. Weiters wird eine Umgebungsvariable WORDPRESS_DB_PASSWORD gesetzt.

Der zweite Container bekommt den Namen mysql und basiert auf dem mysql:5.7 Image. Ports werden keine gemappt, da WordPress direkt auf mysql zugreift und mysql von außen nicht erreichbar sein muss. Zuletzt wird auch hier eine Umgebungsvariable MYSQL_ROOT_PASSWORD gesetzt.
Mit docker-compose up -d werden die zwei Container erstellt und im Hintergrund gestartet.

 

Services

Ein Service entspricht einem Container. Die folgenden Schlüsselwörter können in der Service Sektion verwendet werden.

  • images: welches Image soll für die Instanzierung des Containers verwendet werden.
  • ports: welche Ports des Hostsystems sollen auf die Ports des Containers gemappt werden.
  • environment: setzt System-Variablen innerhalb des Containers.
  • container_name: legt einen bestimmten Namen für einen Container fest. Default wird der Name des Container ORDERNAME_SERVICENAME_1 (für die erste Instanz des Services) benannt.
  • volumes: hier können mountpoints zwischen den Containter und dem Hostsystem erstellt werden. Um Daten zwischen zwei oder mehreren Containern zu sharen müssen alle Container einen Mountpoint auf den gleichen Ordner im Hostsystem erstellen und die Daten werden geshared.
  • networks: legt fest, in welchem Netzwerk sich dieses Service befindet (es muss vorher ein network erzeugt worden sein)
  • depends_on: wenn ein Service von einem anderen abhängt, wird das Service von dem das andere Service abhängt zuerst gestartet. So kann die Startreihenfolge der Services (und somit der Container) definiert werden.

 

Networks

Der Networks Tag erzeugt ein neues Netzwerk. Dieses Netzwerk kann anschliessend von jedem service verwendet werden. Die Eigenschaften werden hier zentral definiert.
Dieser Tag wird unter https://docs.docker.com/compose/compose-file/#network-configuration-reference genau beschrieben.

 

Volumes

Der Volumes Tag erzeugt ein neues Volume. Dieses Volumes kann anschließend von jedem service verwendet werden. Die Eigenschaften werden hier zentral definiert. Dieser Tag wird unter https://docs.dockern.com/compose/compose-file/#volume-configuration-reference genau beschrieben.

 

Docker Compose ohne Installation

TIPP: Sollte auf einem System nur Docker ohne Docker-compose installiert sein oder will man absichtlich auf docker-compose verzichten (um keine nicht benötigten Abhängigkeiten am System installieren zu müssen) gibt es einen Trick Docker-compose dennoch nutzen zu können.
Es kann auf das Docker-Image dduportal/docker-compose zurückgegriffen werden. Dieses Image und die Anwendung werden hier genauer erklärt: https://hub.docker.com/r/dduportal/docker-compose/. Bei diesem Image wird ein Docker Container erstellt in dem docker-compose installiert wird. Die Parameter werden anschließend an docker-compose innerhalb des Containers weitergegeben. Der DockerCompose-Container erstellt und startet die Container, im Falle von up -d , und entfernt danach den Container mit docker-compose wieder.

 

Docker Compose Commands

Immer wenn [SERVICENAME] angegeben ist kann auch optional ein Service angegeben werden und der Befehl gilt nur für dieses Service.

  • docker-compose build  baut die Services
  • docker-compose up -d [SERVICENAME]  erstellt die Container und startet diese. Die Container werden in der korrekten Reihenfolge erstellt und gestartet. Wenn die Container bereits erstellt sind und laufen, bewirkt dieser Befehl einen Restart.
    • -d : startet die Container im Hintergrund
  • docker-compose down  stoppt und entfernt alle Container, Netzwerke, Images und Volumes
  • docker-compose start [SERVICENAME]  startet die Container, dazu müssen diese aber vorher eingestellt worden sein.
  • docker-compose stop [SERVICENAME]  stoppt alle zu dem Stack gehörenden Container.
  • docker-compose rm -f  entfernt alle zu dem Stack gehörenden Container, diese müssen gestoppt sein.
    • -f : erzwingt das Löschen der Container
  • docker-compose logs  zeigt die logs aller zu dem Stack gehörenden Container an. Wenn der Stack mit docker-compose up
    • -d  im Hintergrund gestartet wurde können so die Logsfiles verfolgt werden.
  • docker-compose ps  zeigt die Liste aller dem Stack zugehörenden Container und deren Status an.
  • docker-compose exec SERVICENAME /bin/sh  gleich wie bei docker exec wird ein Befehl innerhalb des Containers ausgeführt. Da die Container, welche von docker-compose erstellt werden, immer den Namen des Ordners in dem sich das docker-compose.yml file befindet, enthält, ist der Name des Containers meist ORDERNAME_SERVICENAME_1 (für die erste Instanz des Services) und könnte auch mit docker exec ORDERNAME_SERVICENAME_1 angesprochen werden. Bei docker-compose exec  kann der Container aber eben direkt über den SERVICENAMEN angesprochen werden. Hier werden die Parameter -it nicht benötigt.
  • docker-compose scale SERVICENAME=X  die Anzahl der laufenden Containerinstanzen des Service SERVICENAME wird auf X erhöht oder verringert. Dabei muss darauf geachtet werden, dass die Definition des Services im docker-compose.yml File skalierbar ist. Wenn zum Beispiel ports: -80:80 angegeben ist kann es zu einem Konflikt kommen. Es kann nur ein Container von diesem Service erstellt werden, da ein zweiter ebenfalls auf den Port 80 des Hostsystem gemappt haben möchte, dieser aber bereits in Verwendung ist. In der docker-compose.yml muss ports: -80:80 zu ports: -80 geändert werden. Docker vergibt und managed die internen Ports selbst.

 

Hier sind nochmals die wichtigsten Docker und Docker Compose Befehle auf einem Blick:

Download Cheatsheet:  Docker_Basics_Cheatsheet

Zum ersten Teil: Docker Basics – Befehle und Life Hacks

Passende Artikel

Antwort schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*