876 Stimmen

Wie man Dateien außerhalb des Docker-Baukontexts einbezieht?

Wie kann ich Dateien ausserhalb des Docker-Build-Kontextes mit dem "ADD"-Befehl in der Docker-Datei einbinden?

Aus der Docker-Dokumentation:

Der Pfad muss sich im Build-Kontext befinden; du kannst nicht ../something/something hinzufügen, weil der erste Schritt eines Docker-Builds darin besteht, das Kontextverzeichnis (und Unterverzeichnisse) an den Docker-Dämon zu senden.

Ich möchte mein gesamtes Projekt nicht neu strukturieren, nur um Docker in dieser Hinsicht anzupassen. Ich möchte alle meine Docker-Dateien im selben Unterverzeichnis behalten.

Es scheint auch, dass Docker noch nicht (und vielleicht nie) symbolische Links unterstützt: Dockerfile ADD-Befehl folgt nicht symlinks auf dem Host #1676.

Das einzige, woran ich denken kann, ist, einen Pre-Build-Schritt einzufügen, um die Dateien in den Docker-Build-Kontext zu kopieren (und meine Versionskontrolle so zu konfigurieren, dass diese Dateien ignoriert werden). Gibt es eine bessere Lösung als das?

716voto

Cyberwiz Punkte 10114

Der beste Weg, dieses Problem zu umgehen, besteht darin, das Dockerfile unabhängig vom Build-Kontext mit -f zu spezifizieren.

Zum Beispiel hat dieser Befehl dem ADD-Befehl Zugriff auf alles in Ihrem aktuellen Verzeichnis.

docker build -f docker-files/Dockerfile .

Aktualisierung: Docker ermöglicht es jetzt, dass das Dockerfile außerhalb des Build-Kontexts liegt (behebt in 18.03.0-ce). Also können Sie auch etwas wie dies tun

docker build -f ../Dockerfile .

98voto

Marcello de Sales Punkte 19324

Ich habe viel Zeit damit verbracht, ein gutes Muster zu finden und zu überlegen, wie man am besten erklären kann, was mit dieser Feature-Unterstützung passiert. Mir wurde klar, dass der beste Weg, es zu erklären, folgendermaßen ist...

  • Dockerfile: Sieht nur Dateien unter seinem eigenen relativen Pfad
  • Kontext: Ein Ort im "Raum", wo die Dateien, die Sie teilen möchten, und Ihr Dockerfile kopiert werden

Also, mit diesen Worten, hier ist ein Beispiel für das Dockerfile, das eine Datei namens start.sh wiederverwenden muss

Dockerfile

Es wird immer aus seinem relativen Pfad laden, wobei das aktuelle Verzeichnis selbst als lokaler Bezugspunkt für die von Ihnen angegebenen Pfade fungiert.

COPY start.sh /runtime/start.sh

Dateien

Unter Berücksichtigung dieser Idee können wir daran denken, mehrere Kopien für die Dockerfiles zu haben, die spezifische Dinge erstellen, aber sie alle benötigen Zugriff auf die start.sh.

./all-services/
   /start.sh
   /service-X/Dockerfile
   /service-Y/Dockerfile
   /service-Z/Dockerfile
./docker-compose.yaml

Unter Berücksichtigung dieser Struktur und der oben genannten Dateien, hier ist ein docker-compose.yml

docker-compose.yaml

  • In diesem Beispiel ist Ihr gemeinsames Kontextverzeichnis das Verzeichnis runtime.
    • Gleicher mentaler Ansatz hier, denken Sie daran, dass alle Dateien unter diesem Verzeichnis in den sogenannten Kontext verschoben werden.
    • Geben Sie einfach das Dockerfile an, das Sie in dasselbe Verzeichnis kopieren möchten. Dies können Sie mit dockerfile angeben.
  • Das Verzeichnis, in dem Ihr Hauptinhalt liegt, ist der tatsächliche Kontext, der festgelegt werden soll.

Das docker-compose.yml sieht wie folgt aus

version: "3.3"
services:

  service-A
    build:
      context: ./all-service
      dockerfile: ./service-A/Dockerfile

  service-B
    build:
      context: ./all-service
      dockerfile: ./service-B/Dockerfile

  service-C
    build:
      context: ./all-service
      dockerfile: ./service-C/Dockerfile
  • all-service wird als Kontext festgelegt, die gemeinsame Datei start.sh wird ebenfalls dorthin kopiert, sowie das von jedem dockerfile spezifizierte Dockerfile.
  • Jeder wird auf seine eigene Weise gebaut und teilt die Startdatei!

85voto

aaron Punkte 1184

Ich finde es oft nützlich, die --build-arg-Option zu diesem Zweck zu nutzen. Zum Beispiel, nachdem ich Folgendes in die Dockerdatei eingefügt habe:

ARG SSH_KEY
RUN echo "$SSH_KEY" > /root/.ssh/id_rsa

Können Sie einfach Folgendes tun:

docker build -t some-app --build-arg SSH_KEY="$(cat ~/file/outside/build/context/id_rsa)" .

Aber beachten Sie die folgende Warnung aus der Docker-Dokumentation:

Warnung: Es wird nicht empfohlen, Build-Zeit-Variablen zum Weitergeben von Geheimnissen wie Github-Keys, Benutzeranmeldeinformationen usw. zu verwenden. Die Werte der Build-Zeit-Variablen sind für jeden Benutzer des Images mit dem docker history-Befehl sichtbar.

61voto

Günter Zöchbauer Punkte 549460

Auf Linux können Sie andere Verzeichnisse anstelle von Symbolischen Links einbinden

mount --bind altesverzeichnis neuesverzeichnis

Siehe https://superuser.com/questions/842642 für weitere Details.

Ich weiß nicht, ob etwas Ähnliches für andere Betriebssysteme verfügbar ist. Ich habe auch versucht, mit Samba einen Ordner freizugeben und ihn in den Docker-Kontext neu zu mounten, was auch funktioniert hat.

24voto

Anshuman Manral Punkte 609

Ich glaube, die einfachere Lösung wäre, den 'Kontext' selbst zu ändern.

Also, anstatt zu geben:

docker build -t hello-demo-app .

was das aktuelle Verzeichnis als Kontext setzt, sagen wir mal, du wolltest das übergeordnete Verzeichnis als Kontext, verwende einfach:

docker build -t hello-demo-app ..

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X