Docker-Image mit Cache auf Build-Server erstellen?

7

Wir haben einen Jenkins CI-Server, der unseren Code von Git abruft, erstellt, ein Docker-Image erstellt und ihn dann an einige Produktionsserver versendet.

Unser Projekt ist hauptsächlich in Python geschrieben, daher beinhaltet "Erstellen" das Ausführen

pip install -r requirements.txt

Das funktioniert gut, außer es ist etwas langsam. Es muss Pakete über das Netzwerk abrufen und für einige von ihnen C-Bibliotheken erstellen (und 'lxml' ist nicht klein!).

In der Entwicklung hatte ich Erfolg pip-acceldamit, diesen Prozess zu beschleunigen. Es hat die gleiche Oberfläche wie pip, speichert jedoch sowohl die Python-Downloads als auch den erstellten C-Code zwischen

pip-accel install -r requirements.txt

ist schnell.

Ich möchte dies für unsere Produktions-Builds tun, aber ich stoße auf einige Hindernisse.

Benötigt natürlich pip-accelein Verzeichnis, in dem der Cache gespeichert wird. Da unser CI-Server die Builds ausführt, ist dies der logische Ort, um ihn zu platzieren. Der pip installBefehl wird jedoch in einem neuen Docker-Container ausgeführt, sodass nicht nur auf ein gemeinsames Verzeichnis auf diesem Server zugegriffen werden kann.

Docker- "Volumes" scheinen für die gemeinsame Nutzung von Verzeichnissen mit Containern konzipiert zu sein, aber unser Build findet (überraschend überraschend) im Inneren statt docker buildund ermöglicht nur docker rundas Anhängen von Volumes. Sie können keine Volumes mit anhängen docker build.

Fehlt mir etwas? Wie kann ich docker buildeinen Cache-Ordner außerhalb des Containers, in dem ich mich befinde, ausführen und für meinen Host freigeben?

Tim
quelle

Antworten:

1

Ich habe nur wenige Reputationen, um Ihre Frage zu kommentieren, daher enthält meine Antwort auch einige Fragen.

Ich habe versucht, dasselbe Setup wie Ihr zu erstellen, aber es wurde minimiert (basierend auf Ihrer obigen Erklärung), und es scheint Verbesserungen mit den eigenen Caching-Mechanismen des Dockers zu geben

Mein Beispiel Dockerfile sieht so aus:

FROM ubuntu:14.04   

RUN apt-get update \
  && apt-get install -y python-pip python-dev build-essential \
  && pip install pip-accel

COPY requirements.txt /requirements.txt

RUN pip-accel install -r /requirements.txt

CMD tail -f /dev/null

Und require.txt sah so aus:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3

Nachdem ich dies zum ersten Mal erstellt hatte (siehe länger), fügte ich eine neue Bibliothek "chardet == 1.0.1" hinzu und jetzt sah meine Anforderungen.txt so aus:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3
chardet==1.0.1

Nach dem Ausführen des Docker-Builds wurde der gesamte Docker-eigene Cache verwendet, der auch die alten Pip-Bibliotheken enthielt

anovil@anovil-Latitude-E6440:~/tmp/serverfault/docker$ time docker build --rm .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM ubuntu:14.04
 ---> 89d5d8e8bafb
...
...
Removing intermediate container 337c23340e7a
Step 5 : CMD tail -f /dev/null
 ---> Running in 5cb25bc75bbe
 ---> d3dfe184934b
Removing intermediate container 5cb25bc75bbe
Successfully built d3dfe184934b

real    0m6.325s
user    0m0.024s
sys 0m0.012s

Da Docker-Build standardmäßig "--force-rm = false", "--no-cache = false" enthält.
Es könnte eine andere Geschichte sein, wenn Ihr Jenkins CI diesen Build als verschiedene Benutzer oder auf verschiedenen Hosts ausführt. Andernfalls müssen die Befehle in Dockerfile bestellt werden.
Wenn Sie noch Fragen haben, können Sie Ihre Docker-Beispieldatei freigeben und hier auch mitteilen, wie oft / häufig Ihre Anforderungen.txt bei jedem Jenkins-Build geändert werden.

Maniankara
quelle