Wiederholte Installation eines Pakets im Docker-Image

1263
Tejas Jayasheel

Ich baute ein Python-Paket namens my-package. Ich habe keine Absicht, es öffentlich zu machen, also erfolgt die Installation meist über unsere internen Server. Kürzlich hat ein älterer Entwickler eine Architektur mit Docker erstellt, bei der die Anwendung gehostet wird und my-packageeine Abhängigkeit darstellt.

Das Problem ist, um das Paket zu testen. Ich muss meinen Code wiederholt in ein Docker-Image kopieren, dann die alte Version des Pakets deinstallieren und den lokalen Code erneut installieren.

  1. Das erneute Erstellen des gesamten Bildes dauert eine halbe Stunde. - Keine Option.
  2. Erstellen Sie ein weiteres Dockerfile FROM-Image und führen Sie nur bestimmte Befehle für COPY aus, und installieren Sie das Pip-Paket. - Meine derzeitige Lösung ist noch nicht sehr effizient.

Ich bin mir ziemlich sicher, dass die Docker-Benutzer auf dieses Problem gestoßen wären. Sie benötigen daher ein Expertengutachten über die effizienteste Vorgehensweise, um damit umzugehen.

UPDATE: Die Dockerfile

# VERSION 1.8.2 # AUTHOR: Matthieu "Puckel_" Roisil # DESCRIPTION: Basic Airflow container # BUILD: docker build --rm -t puckel/docker-airflow . # SOURCE: https://github.com/puckel/docker-airflow  FROM ubuntu:17.10 MAINTAINER Puckel_  # Never prompts the user for choices on installation/configuration of packages ENV DEBIAN_FRONTEND noninteractive ENV TERM linux  # Airflow ARG AIRFLOW_VERSION=1.8.9 ARG AIRFLOW_HOME=/usr/local/airflow  # Define en_US. ENV LANGUAGE en_US.UTF-8 ENV LANG en_US.UTF-8 ENV LC_ALL en_US.UTF-8 ENV LC_CTYPE en_US.UTF-8 ENV LC_MESSAGES en_US.UTF-8 ENV LC_ALL en_US.UTF-8  ENV MATPLOTLIBRC /etc  RUN set -ex \ && buildDeps=' \ python3.6-dev \ libkrb5-dev \ libsasl2-dev \ libssl-dev \ libffi-dev \ build-essential \ libblas-dev \ liblapack-dev \ libpq-dev \ git \ wget \ ' \ && apt-get update -yqq \ && apt-get dist-upgrade -yqq \ && apt-get install -yqq --no-install-recommends \ $buildDeps \ python3.6 \ python3.6-tk \ apt-utils \ curl \ netcat \ locales \ ca-certificates \ sudo \ libmysqlclient-dev \ && ln -s /usr/bin/python3.6 /usr/bin/python \ && sed -i 's/^# en_US.UTF-8 UTF-8$/en_US.UTF-8 UTF-8/g' /etc/locale.gen \ && locale-gen \ && update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 \ && useradd -ms /bin/bash -d $ -u 1500 airflow \ && mkdir $/logs \ && wget https://bootstrap.pypa.io/get-pip.py \ && python get-pip.py \ && rm -rf get-pip.py \ && python -m pip install Cython \ && python -m pip install requests \ && python -m pip install pytz \ && python -m pip install pyOpenSSL \ && python -m pip install ndg-httpsclient \ && python -m pip install pyasn1 \ && python -m pip install Flask-OAuthlib \ && python -m pip install apache-airflow[crypto,celery,postgres,ldap,jdbc,mysql,s3,samba]==$AIRFLOW_VERSION \ && python -m pip install celery[redis]==4.1.0 \ && python -m pip install boto3 \ && python -m pip install pymongo \ && python -m pip install statsd \  && apt-get remove --purge -yqq $buildDeps \ && apt-get clean \ && rm -rf \ /var/lib/apt/lists/* \ /tmp/* \ /var/tmp/* \ /usr/share/man \ /usr/share/doc \ /usr/share/doc-base \ && apt-get autoremove -yqq 

Der wichtige Teil ist am Ende.

ARG CACHEBUST=1  COPY config/matplotlibrc /etc/matplotlibrc COPY script/entrypoint.sh /entrypoint.sh COPY script/shell.sh /shell.sh COPY config/airflow.cfg $/airflow.cfg  RUN chown -R airflow: $  RUN pip install matplotlib seaborn xlsxwriter pandas Jinja2 #Add custom PIP repo - THIS IS OF INTEREST COPY config/pip.conf /etc/pip.conf  RUN python -m pip install my-package  COPY my-package2 /usr/local/my-package2 # RUN pip uninstall my-package2 RUN python -m pip install /usr/local/my-package2  EXPOSE 8080 5555 8793  USER airflow WORKDIR $ ENTRYPOINT ["/entrypoint.sh"] 

Wie Sie sehen, kopiere ich mein-package2 von meinem lokalen Rechner in das Image und führe pip install aus.

  1. Die Bildgröße wird mit jedem Neuaufbau des Bildes größer.
  2. Mengen sind definitiv eine Option, die ich noch nicht ausprobiert habe. Ich mache schon was aus, script/shell.sh was gerade hat $@. Ich habe das als Einstiegspunkt gesetzt und jeden Befehl ausgeführt, den ich ohne viel Feilschen im Bild ausführen möchte.
  3. Ich verwende Docker-Compose, so dass ich jedes Mal, wenn ich mit dem neuen Tag neu aufbaue, in Docker-Compose aktualisieren muss. Im Laufe der Zeit wird es ärgerlich, dies für eine Codeänderung in einer einzelnen Zeile zu tun.
0
Warum wäre das nicht effizient? Wenn Sie das Image zum Wiederherstellen einer zusätzlichen Ebene hinzufügen, sollten Sie die Zeiten verbessern, da Sie die Zwischenprodukte verwenden würden (vorausgesetzt, Sie löschen sie nicht jedes Mal). Zumindest ist das mein Verständnis für Docker. Seth vor 6 Jahren 1
Nicht sehr effizient, da 1. Die Bildgröße mit jedem Versuch immer größer wird (nicht sicher, warum. Technisch sollte es nicht) und meinem Mac wird der Speicher knapp. 2. Sie müssen das alte Tag bei jedem Versuch neu erstellen, neu erstellen und löschen. Ein umständlicher Prozess. Tejas Jayasheel vor 6 Jahren 1
Ich denke, die Idee ist solide (und es scheint, als hätte man sich entschieden, dass Docker verwendet werden muss). Ich denke, es ist besser, sich auf das Problem zu konzentrieren, dass Sie Ihren Code wiederholt kopieren müssen. Wenn Sie eine einzelne Ebene eines Docker-Images ändern, sollte dies auch keine halbe Stunde dauern. Vielleicht können Sie die Reihenfolge ändern, in der Sie Dinge tun, oder einen schnelleren Computer erhalten. Um diesbezüglich Ratschläge zu geben, würden wir definitiv viel mehr Details benötigen. mtak vor 6 Jahren 0
Könnten Sie genug von Ihrer Docker-Datei freigeben, damit wir verstehen, warum es so lange dauert, das Pip-Paket zu installieren. Aber zuerst eine Frage: Warum erstellen Sie nicht ein Image zum Testen, sondern verwenden das Paket vom Host über den Parameter "-v / path / on / host: / path / in / container"? harrymc vor 6 Jahren 0
@ harrymc Mit Docker-Datei und einigen Kommentaren zu meinen Versuchen aktualisiert. Tejas Jayasheel vor 6 Jahren 0
@mtak Mit der Docker-Datei aktualisiert Tejas Jayasheel vor 6 Jahren 0
Fast alle Andockdateien installieren Abhängigkeiten. Warum erstellen Sie nicht ein Bild, das alle enthält, und wiederholt nur die letzten Schritte, um jedes Mal zu testen? harrymc vor 6 Jahren 1

1 Antwort auf die Frage

1
harrymc

Sie müssen einen Teil Ihrer Docker-Datei freigeben, damit wir verstehen können, warum die Installation des Pip-Pakets so lange dauert. Wenn Sie es optimieren möchten, können diese Verweise hilfreich sein:

Eine alternative Lösung ist, anstatt ein Image zum Testen zu erstellen, verwenden Sie einfach das Paket vom Host über den Docker-Parameter von -v /host/directory:/container/directory.

Auf diese Weise können Sie Ihr Paket sofort im Kontext des Containers testen. Daher erstellen Sie das Produktionsimage erst, wenn der Test abgeschlossen ist.

Weitere Informationen finden Sie zum Beispiel: Informationen zu Volumes in Docker .


Aus Ihrer veröffentlichten Docker-Datei scheint es, dass fast alles für die Installation von Abhängigkeiten bestimmt ist. Sie können zu Testzwecken ein Image erstellen, in dem all diese Abhängigkeiten bereits installiert sind. Wiederholen Sie einfach den letzten Schritt für die Installation Ihrer Anwendung, um jedes Mal zu testen.

Zur besseren Lesbarkeit können Sie die Docker - Datei schließlich als mehrstufig schreiben, um Abhängigkeiten von der Produktion zu trennen und möglicherweise auch nur einen endgültigen minimalen Produktionsaufbau zu generieren. Die ONBUILD-Anweisung kann hier nützlich sein.

Nur Sie wissen, was Sie erreichen wollen und was Ihre Einschränkungen sind. Die obigen Links können als Ausgangspunkt dienen, und es gibt viele weitere Artikel zu diesem Thema.

Danke für den Vorschlag. Ich habe am Ende eine Kombination von zwei Lösungen erhalten, die Sie erwähnt haben. In `docker-compose` stelle ich das Volume so ein, dass der Paketcode von Container und Host gemeinsam genutzt wird. Sobald der Paketcode stabilisiert ist, habe ich die nächste Image-Version mit ONBUILD neu erstellt. Die wiederholte Kopie erhöht zwar die Bildgröße, da COPY nicht mehr so ​​häufig vorkommt, kann ich damit leben. Tejas Jayasheel vor 6 Jahren 0