L'installation Pip du module dépendant du langage C avec alpine est une histoire lourde
* .whl
et essayez de l'installer en toute sécuritéTout d'abord, obtenez les comtés de modules requis Cette fois, je présenterai les modules suivants
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
Dans le cas de l'alpin, le format de compression tel que tar et zip est supprimé pour les modules dépendant du langage c. Il est nécessaire de les convertir au format whl.
Il devrait y avoir une bibliothèque requise pour la conversion dans whl, alors installez-la via 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
Vous pouvez également télécharger le module avec pip download
,
Utilisez la commande pip wheel
car elle téléchargera et extraira automatiquement le fichier tar / zip et le construira.
Puisque pip wheel
peut également utiliser l'option -r
, spécifiez le fichier de contrôle de version avec pip freeze> requirements.txt
.
pip wheel --no-cache --wheel-dir=./whl -r requirements.txt
-- no-cache-dir
: ne pas utiliser / créer de cache. S'il n'est pas spécifié, il sera mis en cache en tant que ~ / .tmp
. Les produits au moment de la construction sont également mis en cache.
---- wheel-dir
: destination de sortie du fichier de roue.Malheureusement, dans ce cas ** il échoue en cours de route **
J'utilise requirements.txt
construit dans un autre environnement alpin et pip gelé.
scikit-learn
tombe pendant la construction car numpy
et scipy
ne sont pas disponibles.
Avec pip install -r requirements.txt
, le côté pip l'installera bien, mais [^ 1]
[^ 1]: Puisque l'ordre d'installation de pip est exécuté en une seule fois sans tenir compte des bibliothèques et priorités dépendantes, le même phénomène se produit avec pip install
. Au lieu de cela, les modules qui échouent au milieu en raison d'une «dépendance circulaire» sont évités en réexécutant la construction dès que tous les autres modules ont été installés.
Seulement cette fois, il n'y a pas d'autre choix que de mettre le module dépendant en premier. [^ 2]
[^ 2]: Si scipy ~ = 1.4 dans l'environnement concerné, une erreur se produira et il échouera, alors spécifiez la série 1.3 qui est entrée docilement
pip install cython numpy==1.18.4 scipy==1.3.3
pip wheel --no-cache --wheel-dir=./whl -r requirements.txt
J'essayais de créer une image séparée pour éviter de construire numpy et scipy J'ai l'impression de faire quelque chose qui n'a pas de sens ...?
docker hub
une fois la construction terminéeÉtiqueter correctement et pousser
docker tag 123456789a hoge/builder-image:latest
docker push hoge/builder-image:latest
À partir de là, nous travaillerons sur le fichier dockerfile pour l'environnement d'exécution.
Pour spécifier plusieurs modules avec pip install
, écrivez solidement ou spécifiez un fichier texte avec --requirement
.
Il n'y a aucune spécification qui vous permet de collecter whl dans un répertoire approprié et de l'installer entièrement.
Cette fois, dans une construction en plusieurs étapes, COPY
le répertoire contenant la roue et exécutez la commande suivante pour l'installer à partir de la roue locale.
pip install --no-index --no-deps --no-cache-dir -f ./whl -r requirement.txt
-- no-index
: n'utilisez pas de sites d'index comme PyPi. À utiliser lorsque vous ne voulez pas aller en ligne
---- no-deps
: n'installez pas de modules dépendants. Cependant, il semble que ce ne soit pas le cas s'il est clairement précisé côté module.
---f
, --find-links
: Spécifiez la destination de recherche du module. Utilisez ceci lorsque vous souhaitez spécifier un chemin localLes modules tels que pip et setuptools que vous souhaitez installer avec l'option --upgrade
sont installés séparément dans le fichier texte de mise à niveau.
Le fichier texte référencé par l'option -r
peut être installé sans spécifier la version.
upgrade.txt
pip
setuptools
wheel
Mettez à niveau les modules regroupés dans un répertoire spécifique avec la commande suivante
pip install -U --no-index --no-deps --no-cache-dir -f ./upgrade -r upgrade.txt
Cependant, étant donné que le nombre de fichiers à gérer augmentera, il est préférable d'écrire directement dans le fichier docker, sauf si vous êtes dans un environnement hors ligne.
Vérifiez s'il peut être importé. Créez un fichier shell et appuyez directement sur la commande 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"
Supprimez les fichiers supplémentaires pour réduire le poids de l'image du docker L'image utilisée pour construire n'a besoin que d'un produit, alors effacez tout le reste.
builder-image
apk del --purge .build .testing_build
pip freeze | xargs pip uninstall -y
pip cache purge
Vérifiez la luminosité de l'image construite en supprimant les fichiers supplémentaires. ** 360 Mo ** semble avoir réussi à perdre du poids
# 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
Vient ensuite la disposition du côté de l'environnement d'exécution. Docker python officiel est très intelligent, donc je vais supprimer le fichier en fonction de cela. [^ 3]
[^ 3]: Dans l'environnement d'exécution installé avec -no-cache-dir
spécifié, lorsque pip cache purge
est exécuté, le fichier cache n'est pas trouvé et un code d'erreur est renvoyé. C'est sobre et difficile à utiliser.
execution-image
#Seuls les fichiers nécessaires au module sont regroupés sous la forme d'un nouveau package virtuel,
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 && \
#Effacer tous les packages utilisés au moment de la construction
apk del --purge .build .community_build
#Supprimer les fichiers supplémentaires et les déchets du côté python
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 '{}' +
#Nettoyage de la poussière pour cette gamme d'exécution
rm -rf /tmp/whl
Comparons-le avec le temps où il n'a pas été effacé du côté de l'environnement d'exécution.
# 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
J'ai réussi à le maintenir en dessous de 1 Go.
Sur la base de ce qui précède, notez-le dans le fichier docker. Comme ce sera long, j'ai collé le lien github.
Nous avons rendu possible la mise en place en toute sécurité et relativement rapidement de modules chronophages via pip. L'image du docker était également légèrement plus claire.
Cependant, la partie qui doit avoir plusieurs images est différée.
Étant donné que la cohérence de requirements.txt est requise,
Serait-ce plus facile s'il y avait un mécanisme pour pousser les deux images vers le docker hub
lorsque celui-ci a été mis à jour?
Recommended Posts