Benannte Volumes mit docker-compose

Translated by: gpt-4o-2024-08-06 | Original version

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.