Telefon-Support: +49 2238 570070
docker,concepts

Docker-Compose: Verwaltung von Multi-Container Setups

7. August 2017 Leseszeit ~2 Min

Einzelne Container mittels Docker zu definieren und zu starten ist sehr einfach. Da Docker konzeptionell eng mit sog. 12 Factor Apps verbunden ist, liegt es jedoch nahe, dass eine komplette Umgebung aus mehreren Containern besteht. Dabei stellen sich aber die folgenden Fragen:

  • Wie werden die beteiligten Dienste definiert und konfiguriert
  • Wie ist mit Abhängigkeiten zwischen den Containers umzugehen
  • Wie können Daten zwischen den Container geteilt werden

Und genau hier kommt Docker Compose ins Spiel!

Definition aus der Docker-Compose Dokumentation:

Compose isr ein Werkzeug, um multi-container Docker Applikationen zu definieren und zu betreiben. Mit Compose werden die Dienste einer Applikation in einer Datei definiert und konfiguriert. Mit einem einzigen Kommando können dann alle konfigurierten Dienste, erzeugt und gestartet werden.

Installation

Auf macOS ist Compose bereits in “Docker for Mac” enthalten, auf Linux lässt es sich mit ein paar Zeilen schnell installieren:

sudo DOCKER_COMPOSE_VERSION=1.15.0 curl -L
https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-`uname
-s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Grundlagen

  • Wie gehabt wird die Umgebung der Applikation mittels eines Dockerfiles definiert
  • In der Datei docker-compose.yml werden alle abhängigen Container, Volumes, Ports,… definiert
  • Mit dem Kommando docker-compose up wird die gesamte Umgebung gestartet

Praxisbeispiel

Das folgende Beispiel skizziert die Möglichkeiten von Compose kurz am Beispiel von kong, eine leistungsfähige, per Plugins um Funktionen wie Authentifizierung, Authorizierung(ACLs) und Rate Limiting erweiterbare API-Middleware.

Traefik-Flow

docker-compose.yml:

version: '2.1'

services:
  kong:
    image: kong
    depends_on:
      postgres:
        condition: service_healthy
    links:
      - postgres
    ports:
      - "8000:8000"
      - "8443:8443"
      - "8001:8001"
      - "7946:7946"
      - "7946:7946/udp"
    environment:
      KONG_DATABASE=postgres
      KONG_PG_HOST=postgres

  postgres:
    image: postgres:9.4
    ports: 
       - "5432"
    environment:
      - POSTGRES_USER=kong
      - POSTGRES_DB=kong
    healthcheck:
        test: ["CMD-SHELL", "pg_isready"]
        interval: 30s
        timeout: 15s
        retries: 3

Anstatt ein Image zu verwenden, ist es auch möglich, ein lokales Dockerfile einzubinden.

Ausggangspunkt sei die folgende Verzeichnisstruktur:

~MeinProjekt$ tree -l
.
├── meine_applikation
│   └── Dockerfile
└── postgres
    └── Dockerfile

Compose-Konfiguration, die Images aus den in den Unterverzeichnissen liegenden Dockerfiles erstellt:

version: '2.1'

services:
  app:
    build: meine_applikation/.
    depends_on:
      postgres:
        condition: service_healthy
    links:
      - postgres
    volumes:
      - MeineApplikation:/app
    environment:
      PGHOST: db
      PGUSER: postgres

  postgres:
    build: postgres/.
    ports: 
        - "5432"
    healthcheck:
        test: ["CMD-SHELL", "pg_isready"]
        interval: 30s
        timeout: 10s
        retries: 3