Benannte Volumes mit docker-compose
Während ich an einem Nebenprojekt arbeitete, das docker-compose verwendet, stieß ich auf ein Problem. Eines, dem ich schon zuvor begegnet war, das ich aber nie richtig untersucht oder gelöst hatte.
Hier ist, was ich erreichen möchte:
- Eine Reihe von Diensten innerhalb einer docker-compose-Konfiguration laufen lassen
- Diese Dienste sollen gemountete Freigaben verwenden - eine Freigabe, die von mehr als einem Container genutzt wird.
- Das Problematische: Ich möchte, dass mehrere Container das gleiche Volume verwenden!
Um es kurz zu machen, so funktioniert es reibungslos:
version: '3'
services:
service1:
image: nginx
container_name: service1
ports:
- '81:80'
volumes:
- content:/usr/share/nginx/html
service2:
image: nginx
container_name: service2
ports:
- '82:80'
volumes:
- content:/usr/share/nginx/html
volumes:
content:
driver_opts:
type: none
device: ./data/content
o: bind
Das passiert hier:
- Wir haben 2 Dienste desselben Typs: einfache nginx-Container zu Demonstrationszwecken.
- Beide exponieren ihren (internen) Port 80 auf Port 81 bzw. 82 zur Außenwelt.
- Beide verwenden ein Volume namens content, das im Volumes-Abschnitt definiert ist.
Das Detail, das ich so lange übersehen hatte, war der volumes-Abschnitt mit den driver_opts. Und während ich einige Tests durchführte und alles genau so funktionierte, wie ich es mir erhofft hatte, konnte ich keine ordentliche Dokumentation finden. Hier ist, was die docker-Dokumentation über driver_opts sagt:
Geben Sie eine Liste von Optionen als Schlüssel-Wert-Paare an, die an den Treiber für dieses Volume übergeben werden. Diese Optionen sind treiberabhängig - konsultieren Sie die Dokumentation des Treibers für weitere Informationen.
Bei der Untersuchung, wie die Dinge funktionieren, geben die Inspektionswerkzeuge von Docker einige Einblicke: Dies ist der Mounts-Teil von docker inspect service1
"Mounts": [
{
"Type": "volume",
"Name": "docker-playground_content",
"Source": "/var/lib/docker/volumes/docker-playground_content/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "rw",
"RW": true,
"Propagation": ""
}
]
Zuerst war ich skeptisch wegen dieser Zeile:
"Source": "/var/lib/docker/volumes/docker-playground_content/_data"
Aber es stellt sich heraus, dass meine Daten nicht in diesem von Docker verwalteten Verzeichnis sind, sondern dort, wo ich sie haben wollte. In meinem Fall ist das in ./data/content. Auch der relative Pfad funktioniert einwandfrei.
Quellen
Hier sind die ursprünglichen Quellen, die mir am meisten geholfen haben:
- Docker-Dokumentation - seltsamerweise hat sie überhaupt nicht geholfen…
- Dies war der hilfreichste Stackoverflow-Artikel.
Versionen
Da diese Art von Setups möglicherweise versionsabhängig sind, hier ist mein Setup:
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.9.0
OpenSSL version: OpenSSL 1.1.1h 22 Sep 2020
Und es läuft auf meinem Mac mit Big Sur Version 11.5.2 (mit Intel CPU 😜).
Der Code ist auf Github zu finden.