Docker-compose erklärt
Im letzten Monat haben mich mehrere Leser gefragt, ob ich nicht mal eine kleine Anleitung eine kleine Anleitung zu Docker-compose machen könnte. Mit diesem Artikel möchte ich dem nun nachkommen.
Ich möchte erklären, wie docker-compose funktioniert, wie man es installiert und verwendet. Als Beispiel nehme ich ein eigenes Set-up für Nextcloud, OnlyOffice, Redis, mysql.
version: '3'
services:
db:
image: mariadb:10.5
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: always
volumes:
- ./db:/var/lib/mysql
- /etc/localtime:/etc/localtime:ro
environment:
- MYSQL_ROOT_PASSWORD=password
env_file:
- db.env
networks:
- back
redis:
image: redis:alpine
restart: always
networks:
- back
app:
build: ./app
#image: nextcloud:apache-2302
restart: always
volumes:
- ./cloud:/var/www/html
- /home/ncdata/data:/var/www/html/data
- /etc/localtime:/etc/localtime:ro
- /home/youtube:/home/youtube
- aria2-dl:/var/local/aria2c
environment:
- MYSQL_HOST=db
- REDIS_HOST=redis
env_file:
- db.env
depends_on:
- db
- redis
ports:
- 127.0.0.1:9024:80
- 127.0.0.1:9028:443
networks:
- front
- back
cron:
build: ./app
#image: nextcloud:apache-2302
restart: always
volumes:
- ./cloud:/var/www/html
entrypoint: /cron.sh
depends_on:
- db
- redis
networks:
- front
elasticsearch:
build: ./essearch
restart: always
#command: ['chown', '-R', '1000:1000', '/usr/share/elasticsearch/']
ports:
- "127.0.0.1:9200:9200"
- "127.0.0.1:9300:9300"
environment:
- cluster.name=esearch
- xpack.security.enabled=true
- node.name=esearch
- bootstrap.memory_lock=true
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms750m -Xmx750m"
- ELASTIC_PASSWORD=password
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /home/ncdata/data:/var/www/html/data:ro
- ./ncsearch-data2/:/usr/share/elasticsearch/data
networks:
- front
# self signed
# omgwtfssl:
# image: paulczar/omgwtfssl
# restart: "no"
# volumes:
# - certs:/certs
# environment:
# - SSL_SUBJECT=servhostname.local
# - CA_SUBJECT=my@example.com
# - SSL_KEY=/certs/servhostname.local.key
# - SSL_CSR=/certs/servhostname.local.csr
# - SSL_CERT=/certs/servhostname.local.crt
# networks:
# - proxy-tier
volumes:
db:
cloud:
config:
aria2-dl:
ncsearch-data:
networks:
front:
external:
name: proxy-ssl
back:
Was ist Docker-compose?
Docker-compose dient einem dazu relativ komplizierte Docker Netzwerke aufzusetzen und diese bei Bedarf zu ändern, oder neu zu starten. Auf diese Weise kann man mehrere Container verwalten. Ein Nebeneffekt ist, dass man nur eine YML Datei benötigt.
Aufbau der Datei
Jede Compose Datei trägt den Namen docker-compose.yml und kann auch nicht geändert werden, da sonst das starten der Container nicht funktioniert.
Gestartet werden diese immer mit folgendem Kommando. Dabei sollte man beachten das man solche Container nie als Root User ausführt.
sudo docker-compose up -d
Die Datei ist so aufgebaut.
version: '2.2'
services:
db:
image: mariadb
container_name: name-des-containers
networks:
- container-netzwerk
volumes:
- /lokaler/pfad/:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=superSecret
- MYSQL_PASSWORD=Supersecret23
- MYSQL_DATABASE=database
- MYSQL_USER=databasePW
restart: always
In diesem Beispiel wird ein Container mit einer Datenbank gestartet (mysql) dieser nennt sich db. Folglich kann dieser mit docker-compose up -d db gestartet werden. Will man mehrere Container starten, nimmt man nur docker-compose up -d.
Das Kommando zum starten des Containers kann nur in dem Pfad erfolgen, wo die docker-compose.yml liegt. In einem anderen Pfad wüsste der Server nichts mit dem Kommando anzufangen.
Container_name
Mit container_name gibt man dem Container einen Namen, dies ist sinnvoll, wenn man viele Docker Container geladen hat. Denn ohne dem würden zufällige Namen vergeben werden und man verliert komplett den Überblick.
Image
Image dient dazu damit, das richtige Container Image geladen werden kann. Diese findet man im Netz unter https://hub.docker.com.
Networks
Wenn man mehrere Container miteinander verknüpfen will, geschieht dies in Netzwerken. Vergleichbar mit dem lokalen Netzwerken zu Hause, wo die einzelnen Rechner untereinander reden können, von außen (Router) kein Zugriff erfolgen kann. Wie in diesem Beispiel könnte es aussehen.
version: '3'
Services:
db:
image:
port:
- 3306
networks:
- netzwerkname
website:
image:
port:
- 8080:80
- 4443:443
networks:
- netwerkname
restart: always
networks:
netzwerkname:
Volume
Mit einem Volume kann man Pfade auf dem Host-System mit Pfaden innerhalb der Container verknüpfen. Auf diese Weise bleiben Dateien bei einem Update des Containers, oder bei einem Neustart des Containers/Servers erhalten. Wenn man kein Volume setzt, gehen alle Daten verloren, sollte man einen Neustart machen. Ein symbolischer Link macht nur Sinn, wenn der Pfad im Container auch Daten beinhaltet.
volumes:
- /lokaler/pfad/:/var/lib/mysql
Bei MySQL wäre der Pfad zum Beispiel /var/lib/mysql. Bei WordPress meist /var/www/html
Volumes_from
Mit diesem Befehl lassen sich alle Volumes eines anderen Containers übernehmen. So muss man nichts doppelt schreiben.
Hier ein Beispiel:
version: "2"
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes_from:
- redis:rw
postgres:
image: postgres:9.4
volumes:
- /data/webapp
backup:
image: postgres:9.4
volumes:
- /var/lib/backup/data
environment
Mit einem Environment werden Kommandos innerhalb des Containers ausgeführt.
In unserem Beispiel, oben im Artikel, wird eine Datenbank beim ersten Containerstart erstellt, sowie der dazugehörige Benutzer und das Datenbankpasswort. Zudem noch ein MySQL Root Nutzer erstellt, da sonst kein Editieren oder erstellen der Datenbanken möglich wäre.
Eine Datenbank benötigt man eigentlich immer, sei es für eine Webseite, einer Cloud, eines E-Mail-Servers oder sonstigen Dingen.
Ports
Mit der Angabe Ports ist es möglich einen Container über einen Port anzusprechen, beispielsweise via dem Nginx Web Server.
Ports: - 80:80 - 443:443
Hier wird der Port angeben der im Container genutzt wird. Sowie der Port am Host System. Dies kann sich ein ganz anderer sein, sollte beispielsweise der Port 80 oder 443 schon belegt sein. Dies wäre dann
- 4444:443
restart
mit Restart wird dem Docker Dämon erklärt das dieser Container bei jedem Neustart des Servers mitgestartet werden soll. Mögliche Befehle wären
restart: always restart: unless-stopped
Beim ersten Befehl wird der Container immer mit gestartet, beim zweiten nur bis du ihn selbst gestoppt hast.
Links
Mit links kann man einen Hostnamen eines Containers, einem anderen Container zur Verfügung stellen.
mynginx: image: nginx links: myphp-fpm myphp-fpm: image: php:fpm
Build
Mit dem Build Befehl lassen sich eigene Images erstellen. Dazu benötigt man ein zusätzliches Dockerfile. In diesem werden das zu nutzende Image festgelegt und Befehle eingetragen, die beim Erstellen des Images durchgeführt werden sollen.
In diesem Beispiel spricht der Nginx Container den PHP-FPM Container nicht mit der IP an, sondern mit dem Containernamen. Eindeutig praktisch. Hier ein Beispiel für ein Dockerfile:
FROM ubuntu:18.04 #mit Welchem Betriebssystem das Image laufen soll
MAINTAINER # nennung des Entwicklers
ADD ./mysql-setup.sh /tmp/mysql-setup.sh #kopieren einer Datei in das Image
RUN /bin/sh /tmp/mysql-setup.sh #ausführen eines Befehls
RUN apt-get update && apt-get ugrade #Update von installierten Packeten im Image
[..]
ausgeführt wird dies dann mit
docker build -t containername .
Quellen und weitere Infos: ab-heute-programmieren.de, docs.docker.com
Comments ()