Frage Wiederholte Installation eines Pakets in Docker Image


Ich habe ein Python-Paket namens my-package. Ich habe nicht die Absicht, es öffentlich zu machen, daher erfolgt die Installation hauptsächlich über unsere internen Server. Kürzlich hat ein leitender Entwickler eine Architektur mit dem Andockfenster erstellt, auf dem die Anwendung gehostet wird my-package ist eine Abhängigkeit.

Das Problem ist, um das Paket zu testen, ich wiederholt meinen Code in Docker Bild kopieren, dann alte Version des Pakets deinstallieren und neu installieren aus dem lokalen Code.

  1. Der Wiederaufbau des gesamten Bildes dauert wiederum eine halbe Stunde. - Keine Option.
  2. Erstellen Sie ein anderes Dockerfile FROM vorhandenes 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 Nutzer des Dockers auf dieses Problem gestoßen wären und daher ein Gutachten über den effizientesten Weg benötigen.

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 ${AIRFLOW_HOME} -u 1500 airflow \
    && mkdir ${AIRFLOW_HOME}/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_HOME}/airflow.cfg

RUN chown -R airflow: ${AIRFLOW_HOME}

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 ${AIRFLOW_HOME}
ENTRYPOINT ["/entrypoint.sh"]

Wie Sie sehen können, kopiere ich my-package2 von meinem lokalen Rechner auf das Image und führe pip install aus.

  1. Die Bildgröße wird jedes Mal größer, wenn ich das Bild neu anlege.
  2. Volumes ist definitiv eine Option, die ich noch nicht ausprobiert habe. Ich nutze schon script/shell.sh  was gerade hat $@. Ich stelle das als Einstiegspunkt ein und führe jeden Befehl aus, den ich ohne viel Feilschen im Bild ausführen möchte.
  3. Ich benutze docker-compose, also muss ich jedes Mal, wenn ich mit dem neuen Tag neu anlege, auch in docker-compose updaten. Im Laufe der Zeit wird es nervig, dies für eine einzelne Zeile Codeänderung zu tun.

0
2017-12-07 04:57


Ursprung


Warum sollte das nicht effizient sein? Wenn Sie das Bild neu aufbauen, sollten Sie es, wenn Sie es zu einer zusätzlichen Ebene machen, ebenso wie die Intermediate verbessern (vorausgesetzt, Sie löschen sie nicht jedes Mal). Zumindest ist das mein Verständnis für Docker. - Seth
Nicht sehr effizient, weil 1. Die Bildgröße steigt mit jedem Versuch (nicht sicher warum. Technisch sollte es nicht) und mein Mac ist nicht mehr genügend Speicher. 2. Sie müssen das alte Tag bei jedem Versuch neu speichern, neu aufbauen und löschen. Ziemlich mühsam. - Tejas Jayasheel
Ich denke, die Idee ist solide (und es scheint, als wäre es entschieden zum Sie, dass Docker verwendet werden muss). Ich denke, es wäre 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 nicht eine halbe Stunde dauern. Vielleicht können Sie die Reihenfolge ändern, in der Sie Dinge erledigen, oder einen schnelleren Computer bekommen. Um dazu einen Rat zu geben, würden wir definitiv viel mehr Details benötigen. - mtak
Können Sie genug von Ihrer Docker-Datei teilen, damit wir verstehen, warum es so lange dauert, das Pip-Paket zu installieren. Aber zuerst eine Frage: Warum nicht, anstatt ein Bild zum Testen zu erstellen, verwenden Sie einfach das Paket vom Host über den Parameter von -v /path/on/host:/path/in/container? - harrymc
Fast die gesamte dockerfile installiert Abhängigkeiten. Warum erstellen Sie kein Bild, das alle enthält, wiederholen Sie einfach die letzten paar Schritte, um jedes Mal zu testen? - harrymc


Antworten:


Sie müssen etwas von Ihrer Dockerdatei teilen, damit wir verstehen, warum dauert so lange, um das Pip-Paket zu installieren. Wenn Sie es optimieren möchten, können diese Referenzen helfen:

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

Dadurch können Sie Ihr Paket sofort im Kontext des Container, so dass Sie nur das Produktionsbild beim Testen erstellen ist komplett.

Viel mehr Informationen können zum Beispiel gefunden werden: Verstehen von Volumes in Docker.


Von Ihrer geposteten Dockerdatei scheint es, dass fast alles dafür gedacht ist Abhängigkeiten installieren. Zum Testen können Sie ein Bild erstellen, in dem all diese Abhängigkeiten enthalten sind bereits installiert, Wiederholen Sie dann den letzten Schritt für die Installation Ihrer Anwendung jedes Mal zum Prüfen.

Zur besseren Lesbarkeit können Sie die Dockerdatei schließlich als mehrstufig, um Abhängigkeiten zu trennen - aufbauend auf Produktion und vielleicht auch um nur einen letzten minimalen Produktionsaufbau zu erzeugen. Das ONBUILD-Anweisung könnte 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 dem Thema gefunden werden.


1
2017-12-24 10:10



Danke für den Vorschlag. Ich endete mit einer Kombination von zwei Lösungen, die Sie erwähnt haben. Im docker-compose, Setze ich das Volumen so, dass der Paketcode zwischen Behälter und Wirt geteilt wird. Sobald der Paketcode stabilisiert ist, habe ich die nächste Version des Bildes mit Hilfe von ONBUILD. Obwohl die wiederholte Kopie die Bildgröße erhöht, da COPY nicht so häufig ist wie vorher, kann ich damit leben. - Tejas Jayasheel