Die Pip-Installation eines C-sprachabhängigen Moduls mit Alpine macht es schwer
* .whl
mit und versuchen Sie es sicher zu installierenHolen Sie sich zunächst die erforderlichen Modul-Counties Dieses Mal werde ich die folgenden Module vorstellen
requirements.txt
cycler==0.10.0
Cython==0.29.17
h5py==2.10.0
joblib==0.14.1
kiwisolver==1.2.0
matplotlib==3.2.1
numpy==1.18.4
pandas==1.0.3
Pillow==7.1.2
pyparsing==2.4.7
python-dateutil==2.8.1
pytz==2020.1
scikit-learn==0.22.2.post1
scipy==1.3.3
six==1.14.0
Im Falle von Alpine fällt das Komprimierungsformat wie tar und zip für c-sprachabhängige Module ab. Diese müssen in das whl-Format konvertiert werden.
Für die Konvertierung in whl sollte eine Bibliothek erforderlich sein. Installieren Sie sie daher über apk
apk update \
&& apk add --virtual .build --no-cache openblas-dev lapack-dev freetype-dev
...
&& apk add --virtual .community_build --no-cache -X http://dl-cdn.alpinelinux.org/alpine/edge/community hdf5-dev
Sie können das Modul auch mit "pip download" herunterladen.
Verwenden Sie den Befehl pip Wheel
, da er die tar / zip-Datei herunterlädt, automatisch extrahiert und erstellt.
Da "Pip Wheel" auch die Option "-r" verwenden kann, geben Sie die Versionsdatei mit "Pip Freeze> Requirements.txt" an.
pip wheel --no-cache --wheel-dir=./whl -r requirements.txt
-- no-cache-dir
: Verwenden / erstellen Sie keinen Cache. Wenn nicht angegeben, wird es als "~ / .tmp" zwischengespeichert. Build-Time-Produkte werden ebenfalls zwischengespeichert.
---- Rad-Verzeichnis
: Ausgabeziel der Raddatei.Leider scheitert es in diesem Fall ** unterwegs **
Ich verwende require.txt
, das in einer anderen alpinen Umgebung gebaut und pip eingefroren wurde.
scikit-learn
fällt während des Builds, weil numpy
und scipy
nicht verfügbar sind.
Mit pip install -r require.txt
wird die Pip-Seite es gut installieren, aber [^ 1]
[^ 1]: Da die Installationsreihenfolge von pip auf einmal ausgeführt wird, ohne abhängige Bibliotheken und Prioritäten zu berücksichtigen, tritt das gleiche Phänomen bei "pip install" auf. Stattdessen werden Module, die aufgrund "zirkulärer Abhängigkeit" in der Mitte ausfallen, vermieden, indem der Build erneut ausgeführt wird, sobald alle anderen Module installiert wurden.
Nur dieses Mal bleibt keine andere Wahl, als die abhängigen Module an die erste Stelle zu setzen. [^ 2]
[^ 2]: Wenn scipy ~ = 1.4 in der vorliegenden Umgebung ist, tritt ein Fehler auf und er schlägt fehl. Geben Sie daher die 1.3-Reihe an, die gehorsam eingegeben wurde
pip install cython numpy==1.18.4 scipy==1.3.3
pip wheel --no-cache --wheel-dir=./whl -r requirements.txt
Ich habe versucht, ein separates Bild zu erstellen, um zu vermeiden, dass es numpy und scipy wird Ich habe das Gefühl, etwas Sinnloses zu tun ...?
Richtig markieren und drücken
docker tag 123456789a hoge/builder-image:latest
docker push hoge/builder-image:latest
Von hier aus werden wir an der Docker-Datei für die Ausführungsumgebung arbeiten.
Um mehrere Module mit pip install
anzugeben, schreiben Sie solide oder geben Sie eine Textdatei mit --requirement
an.
Es gibt keine Spezifikation, mit der Sie whl in einem geeigneten Verzeichnis sammeln und vollständig installieren können.
Installieren Sie dieses Mal vom lokalen Rad aus das Verzeichnis COPY, das das Rad im mehrstufigen Build enthält, und führen Sie den folgenden Befehl aus.
pip install --no-index --no-deps --no-cache-dir -f ./whl -r requirement.txt
-- no-index
: Verwenden Sie keine Indexseiten wie PyPi. Verwenden Sie diese Option, wenn Sie nicht online gehen möchten
---- no-deps
: Installieren Sie keine abhängigen Module. Dies scheint jedoch nicht der Fall zu sein, wenn dies auf der Modulseite eindeutig angegeben ist.
---f
, --find-links
: Geben Sie das Suchziel des Moduls an. Verwenden Sie diese Option, wenn Sie einen lokalen Pfad angeben möchtenModule, die Sie mit der Option "--upgrade" installieren möchten, z. B. pip und setuptools, werden separat in der Upgrade-Textdatei installiert.
Die Textdatei, auf die mit der Option -r
verwiesen wird, kann ohne Angabe der Version installiert werden.
upgrade.txt
pip
setuptools
wheel
Aktualisieren Sie die in einem bestimmten Verzeichnis gruppierten Module mit dem folgenden Befehl
pip install -U --no-index --no-deps --no-cache-dir -f ./upgrade -r upgrade.txt
Da sich jedoch die Anzahl der zu verwaltenden Dateien erhöht, ist es besser, direkt in die Docker-Datei zu schreiben, es sei denn, Sie befinden sich in einer Offline-Umgebung.
Überprüfen Sie, ob es importiert werden kann. Erstellen Sie eine Shell-Datei und drücken Sie direkt den Befehl RUN
.
import_test.sh
#!/bin/sh
python -c "import numpy"
python -c "import scipy"
python -c "import h5py"
python -c "import pandas"
python -c "import matplotlib"
python -c "import sklearn"
Entfernen Sie zusätzliche Dateien, um das Gewicht des Docker-Images zu verringern Das Image, das zum Erstellen von whl verwendet wird, muss nur ein Produkt enthalten. Löschen Sie also alles andere.
builder-image
apk del --purge .build .testing_build
pip freeze | xargs pip uninstall -y
pip cache purge
Überprüfen Sie, wie hell das erstellte Image ist, indem Sie die zusätzlichen Dateien löschen. ** 360MB ** scheint beim Abnehmen erfolgreich gewesen zu sein
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
naka345/wheel_build latest b6c9df898334 9 minutes ago 1.04GB
naka345/wheel_build latest 3236cf2f87de 2 days ago 639MB
Als nächstes folgt die Anordnung auf der Seite der Ausführungsumgebung. Offizieller Python Docker ist sehr intelligent, daher werde ich die Datei entsprechend löschen. [^ 3]
[^ 3]: In der Ausführungsumgebung, in der -no-cache-dir
installiert ist, wird bei Ausführung von pip cache purge
die Cache-Datei nicht gefunden und ein Fehlercode zurückgegeben. Es ist nüchtern und schwer zu bedienen.
execution-image
#Sammeln Sie nur die für das Modul erforderlichen Dateien als neues virtuelles Paket.
find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
| xargs -rt apk add --no-cache --virtual .module-rundeps && \
#Löschen Sie alle zur Erstellungszeit verwendeten Pakete
apk del --purge .build .community_build
#Löschen Sie zusätzliche Dateien und Müll auf der Python-Seite
find /usr/local -depth \
\( \
\( -type d -a \( -name test -o -name tests -o -name idle_test \) \) \
-o \
\( -type f -a \( -name '*.pyc' -o -name '*.pyo' \) \) \
\) -exec rm -rf '{}' +
#Staubreinigung für diesen Ausführungsbereich
rm -rf /tmp/whl
Vergleichen wir es mit der Zeit, als es auf der Seite der Ausführungsumgebung nicht gelöscht wurde.
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
naka345/wheel_install latest f0df8a9887de 3 hours ago 1.29GB
↓
naka345/wheel_install latest 27b4805053f2 3 hours ago 968MB
Ich habe es geschafft, es unter 1 GB zu halten.
Schreiben Sie es auf der Grundlage des oben Gesagten in die Docker-Datei. Da es lange dauern wird, habe ich den [Github-Link] eingefügt (https://github.com/naka345/qiita_product/tree/master/docker/wheel_build).
Wir haben es möglich gemacht, zeitaufwändige Module sicher und relativ schnell per Pip einzubringen. Das Docker-Bild war auch etwas heller.
Der Teil, der mehrere Bilder enthalten muss, wird jedoch zurückgestellt. Da die Konsistenz von require.txt erforderlich ist, Wäre es einfacher, wenn es einen Mechanismus gäbe, mit dem beide Bilder bei der Aktualisierung auf den Docker-Hub übertragen werden könnten?
Recommended Posts