2017-07-20 4 views
0

Ich möchte einige benutzerdefinierte Plug-Ins in ein offizielles Docker-Basisbild einer Anwendung einbeziehen und aktivieren.Loop/Iterate in Dockerfile

So sieht Verzeichnisstruktur aus;

. 
+-- Dockerfile 
+-- plugins 
| +-- plugin_1 
| +-- plugin_2 
| +-- plugin_3 
| +-- ... 
| +-- plugin_n 

Dockerfile wie folgt aussehen, wenn ich Plug-in plugin_1, plugin_3, plugin_7 und plugin_8 umfassen müssen;

FROM myapp_officialimage 

COPY plugins/plugin_1/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_1 

COPY plugins/plugin_3/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_3 

COPY plugins/plugin_7/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_7 

COPY plugins/plugin_8/* /usr/lib/myapp/plugins/ 
RUN myapp-plugins.sh enable plugin_8 

CMD ["myapp-start.sh"] 

Frage ist ist es möglich, iterieren/Schleife über eine Liste, um über vorformulierten zu beseitigen?

Zum Beispiel wäre Dockerfile wie unten sauberer und wartungsfreundlicher;

FROM myapp_officialimage 

ENV CUSTOM_PLUGIN_LIST="plugin_1 plugin_3 plugin_7 plugin_8" 

for plugin in $CUSTOM_PLUGIN_LIST; \ 
do \ 
    COPY plugins/$plugin/* /usr/lib/myapp/plugins/ \ 
    RUN myapp-plugins.sh enable $plugin \ 
done 

CMD ["myapp-start.sh"] 
+2

Das wird zwei Ebenen für das Bild für jedes Plugin erstellen. Kannst du das nicht mit einem Shell-Skript machen? Das wird ein "RUN" sein. – Grimmy

+0

Können diese Plugins als Pakete in irgendeiner Form heruntergeladen werden? Dann würden Sie eine Anforderungsliste erstellen und die Pakete in das Bild herunterladen. – Grimmy

+0

'docker build' findet in einem Build-Server statt, während das eingebaute Image in einer Produktionsumgebung ausgeführt wird. Der Host in der Produktion enthält nicht das Verzeichnis 'plugins' und das Produktionsnetzwerk hat keinen Zugriff zum Herunterladen von Plug-in-Dateien. Ich muss diese Plugins während der Kompilier- und Erstellungszeit bündeln und das resultierende Bild dann an die Produktion senden. –

Antwort

0

In Ihrem Fall würde ich ein neues Plug-ins zusammen Ordner vorbereiten mit einem (möglicherweise erzeugt oder handwerklich) Skript, das sie installiert. Fügen Sie den echten Plugins-Ordner zu .dockerignore hinzu. Dann kopieren Sie in den neuen Ordner und führen das Installationsskript aus. Dadurch wird auch die Größe des Contexts verringert, den Sie vor dem Buildup in Docker hochladen. Sie sind sowieso dabei, die Abhängigkeiten manuell auszuwählen, also sollte die Arbeit vorher (vor Ihnen build) gut funktionieren.

Im Build-System Sie Sie so etwas wie tun sollten:

collect_plugins.sh # Creates the new plugin folder and install script 
docker build <params> 

Die beiden Schichten dann sein könnten:

COPY plugins_selected/ /usr/lib/myapp/plugins/ 
RUN /usr/lib/myapp/plugins/install.sh 

Wenn Sie den Kontext es das machen Andockfenster Sie senden vorbereiten Dockerfile viel einfacher (eine gute Sache). Wir lösen das Problem einfach vor build.

Normalerweise werden Abhängigkeiten über das Netzwerk mithilfe eines Paketmanagers abgerufen oder einfach über http (s) heruntergeladen. Es ist nicht unbedingt falsch, sie in den Build-Kontext zu kopieren, wie Sie es tun, aber es wird ein bisschen peinlicher.

Schauen wir uns an, wie Docker verarbeitet die Dockerfile (leicht simiplified).

Wenn Sie build aufrufen, lädt Docker alle Dateien im Kontext in die Docker Engine (mit Ausnahme der in .dockerignore genannten Pfade) und beginnt mit der Verarbeitung der Dockerfile. Der Zweck besteht darin, Dateisystemebenen zu erzeugen, die das endgültige Bild darstellen.

Wenn Sie Vorgänge wie RUN ausführen, startet Docker tatsächlich einen Container, um die Befehle auszuführen, und fügt dann die resultierende Ebene zum Bild hinzu. Das einzige, was tatsächlich in der Produktion läuft, ist das, was Sie in CMD und ENTRYPOINT am Ende der Dockerfile angeben.

Versuchen Sie, so wenige Ebenen wie möglich zu erstellen.

Die dockerfile best practices guide covers the basics.