python:3.8-slim-buster
Lire le Dockerfile
▍Image de base
Commençons par une image de base:
FROM debian:buster-slim
Il s'avère que l'image de base
python:3.8-slim-buster
est Debian GNU / Linux 10 - la version stable actuelle de Debian, également connue sous le nom de Buster (les versions de Debian sont nommées d'après des personnages de Toy Story). Buster est, si quelqu'un est intéressé, le chien d'Andy.
Ainsi, au cœur de l'image qui nous intéresse se trouve la distribution Linux, qui garantit son fonctionnement stable. Des corrections de bogues sont régulièrement publiées pour cette distribution. La variante a
slim
moins de packages installés que la variante régulière. Là, par exemple, il n'y a pas de compilateurs.
▍ Variables d'environnement
Jetons maintenant un œil aux variables d'environnement. Le premier garantit qu'il est ajouté le
/usr/local/bin
plus tôt possible $PATH
.
# python, ,
ENV PATH /usr/local/bin:$PATH
L'image est conçue pour que Python soit installé dans
/usr/local
. En conséquence, cette construction garantit que les exécutables installés seront utilisés par défaut.
Ensuite, jetons un coup d'œil aux paramètres de langue:
# http://bugs.python.org/issue19846
# > "LANG=C" Linux * Python 3*, .
ENV LANG C.UTF-8
Pour autant que je sache, Python 3 moderne, par défaut, et sans ce paramètre, utilise UTF-8. Je ne suis donc pas sûr que cette ligne soit nécessaire dans le Dockerfile en question ces jours-ci.
Il existe également une variable d'environnement qui contient des informations sur la version actuelle de Python:
ENV PYTHON_VERSION 3.8.5
Il existe également une variable d'environnement à clé GPG dans le Dockerfile, qui est utilisée pour vérifier le code source Python chargé.
▍ Dépendances d'exécution
Python a besoin de quelques packages supplémentaires pour fonctionner:
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
netbase \
&& rm -rf /var/lib/apt/lists/*
Le premier package ,,
ca-certificates
contient une liste de certificats CA standard. Quelque chose de similaire est utilisé par le navigateur pour valider les adresses . Cela permet à Python wget
et à d'autres outils de valider les certificats fournis par les serveurs.
Le deuxième package,
netbase
qui effectue l'installation dans /etc
plusieurs fichiers, est nécessaire pour configurer le mappage de certains noms vers certains ports et protocoles. Par exemple, il /etc/services
est chargé de configurer la correspondance des noms de service, comme https
, avec les numéros de port. Dans ce cas, c'est le cas 443/tcp
.
▍Installez Python
La boîte à outils de compilation est en cours d'installation. À savoir, la source Python est téléchargée et compilée, puis les paquets Debian inutiles sont désinstallés:
RUN set -ex \
\
&& savedAptMark="$(apt-mark showmanual)" \
&& apt-get update && apt-get install -y --no-install-recommends \
dpkg-dev \
gcc \
libbluetooth-dev \
libbz2-dev \
libc6-dev \
libexpat1-dev \
libffi-dev \
libgdbm-dev \
liblzma-dev \
libncursesw5-dev \
libreadline-dev \
libsqlite3-dev \
libssl-dev \
make \
tk-dev \
uuid-dev \
wget \
xz-utils \
zlib1g-dev \
# Stretch "gpg"
$(command -v gpg > /dev/null || echo 'gnupg dirmngr') \
\
&& wget -O python.tar.xz "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz" \
&& wget -O python.tar.xz.asc "https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$GPG_KEY" \
&& gpg --batch --verify python.tar.xz.asc python.tar.xz \
&& { command -v gpgconf > /dev/null && gpgconf --kill all || :; } \
&& rm -rf "$GNUPGHOME" python.tar.xz.asc \
&& mkdir -p /usr/src/python \
&& tar -xJC /usr/src/python --strip-components=1 -f python.tar.xz \
&& rm python.tar.xz \
\
&& cd /usr/src/python \
&& gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)" \
&& ./configure \
--build="$gnuArch" \
--enable-loadable-sqlite-extensions \
--enable-optimizations \
--enable-option-checking=fatal \
--enable-shared \
--with-system-expat \
--with-system-ffi \
--without-ensurepip \
&& make -j "$(nproc)" \
LDFLAGS="-Wl,--strip-all" \
&& make install \
&& rm -rf /usr/src/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' -o -name '*.a' \) \) \
-o \( -type f -a -name 'wininst-*.exe' \) \
\) -exec rm -rf '{}' + \
\
&& ldconfig \
\
&& apt-mark auto '.*' > /dev/null \
&& apt-mark manual $savedAptMark \
&& find /usr/local -type f -executable -not \( -name '*tkinter*' \) -exec ldd '{}' ';' \
| awk '/=>/ { print $(NF-1) }' \
| sort -u \
| xargs -r dpkg-query --search \
| cut -d: -f1 \
| sort -u \
| xargs -r apt-mark manual \
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
&& rm -rf /var/lib/apt/lists/* \
\
&& python3 --version
Il se passe beaucoup de choses ici, mais le plus important est ceci:
- Python est installé dans
/usr/local
. - Tous les fichiers .pyc sont supprimés.
- Les packages, en particulier -
gcc
et d'autres du type qui étaient nécessaires pour compiler Python, sont supprimés une fois qu'ils ne sont plus nécessaires.
En raison du fait que tout cela se produit en une seule commande
RUN
, le compilateur n'est stocké dans aucune des couches, ce qui permet de maintenir une taille d'image compacte.
Ici, vous pouvez noter que Python a besoin d'une bibliothèque pour compiler
libbluetooth-dev
. Cela me semblait inhabituel, alors j'ai décidé de le découvrir. En fait, Python peut créer des sockets Bluetooth, mais uniquement s'il est compilé à l'aide de cette bibliothèque.
▍ Configuration du lien symbolique
L'étape suivante consiste
/usr/local/bin/python3
à attribuer un lien symbolique /usr/local/bin/python
, ce qui permet à Python d'être invoqué de différentes manières:
# ,
RUN cd /usr/local/bin \
&& ln -s idle3 idle \
&& ln -s pydoc3 pydoc \
&& ln -s python3 python \
&& ln -s python3-config python-config
▍Installer pip
Le gestionnaire de packages
pip
a son propre calendrier de publication qui diffère du calendrier de publication de Python. Par exemple, ce Dockerfile installe Python 3.8.5, publié en juillet 2020. Et pip 20.2.2 est sorti en août, après la sortie de Python, mais le Dockerfile est conçu pour avoir une nouvelle version installée pip
:
# "PIP_VERSION", pip : "ValueError: invalid truth value '<VERSION>'"
ENV PYTHON_PIP_VERSION 20.2.2
# https://github.com/pypa/get-pip
ENV PYTHON_GET_PIP_URL https://github.com/pypa/get-pip/raw/5578af97f8b2b466f4cdbebe18a3ba2d48ad1434/get-pip.py
ENV PYTHON_GET_PIP_SHA256 d4d62a0850fe0c2e6325b2cc20d818c580563de5a2038f917e3cb0e25280b4d1
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
apt-get update; \
apt-get install -y --no-install-recommends wget; \
\
wget -O get-pip.py "$PYTHON_GET_PIP_URL"; \
echo "$PYTHON_GET_PIP_SHA256 *get-pip.py" | sha256sum --check --strict -; \
\
apt-mark auto '.*' > /dev/null; \
[ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*; \
\
python get-pip.py \
--disable-pip-version-check \
--no-cache-dir \
"pip==$PYTHON_PIP_VERSION" \
; \
pip --version; \
\
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 '{}' +; \
rm -f get-pip.py
Une fois ces opérations terminées, comme auparavant, tous les fichiers .pyc sont supprimés.
▍ Point d'entrée d'image
En conséquence, le point d'entrée de l'image est spécifié dans le Dockerfile:
CMD ["python3"]
En utilisant à la
CMD
place, ENTRYPOINT
nous lançons l'image, par défaut, nous avons accès à python:
$ docker run -it python:3.8-slim-buster
Python 3.8.5 (default, Aug 4 2020, 16:24:08)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Mais, si nécessaire, vous pouvez spécifier d'autres fichiers exécutables lors du démarrage de l'image:
$ docker run -it python:3.8-slim-buster bash
root@280c9b73e8f9:/#
Résultat
Voici ce que nous avons appris en analysant le fichier Dockerfile officiel de l'image Python
slim-buster
.
▍L'image comprend Python
Bien que cela puisse sembler évident, il convient de prêter attention à la manière exacte dont Python est inclus dans l'image. À savoir, cela se fait en l'installant dans
/usr/local
.
Les programmeurs utilisant cette image font parfois la même erreur, qui est de réinstaller la version Debian de Python:
FROM python:3.8-slim-buster
# :
RUN apt-get update && apt-get install python3-dev
Lorsque vous exécutez cette commande,
RUN
Python sera de nouveau installé, mais dans /usr
, pas dans /usr/local
. Et ce ne sera généralement pas la version de Python installée dans /usr/local
. Et le programmeur qui a utilisé le fichier Docker ci-dessus n'a probablement pas besoin de deux versions différentes de Python dans la même image. C'est principalement la raison de la confusion.
Et si quelqu'un a vraiment besoin d'une version Debian de Python, il serait préférable de l'utiliser comme image de base
debian:buster-slim
.
▍ L'image comprend la dernière version de pip
Par exemple, la dernière version de Python 3.5 datait de novembre 2019, mais l'image Docker
python:3.5-slim-buster
inclut pip
celle qui est sortie en août 2020. C'est (généralement) une bonne chose car cela signifie que nous avons à notre disposition les correctifs de bogues les plus récents et les améliorations de performances. Cela signifie également que nous pouvons bénéficier d'une assistance pour les nouvelles options de roues.
▍ Tous les fichiers .pyc sont supprimés de l'image
Si vous souhaitez accélérer un peu le démarrage du système, vous pouvez compiler indépendamment le code source de la bibliothèque standard au format .pyc. Ceci est fait en utilisant le module compileall .
▍Image n'installe pas les mises à jour de sécurité Debian
Bien que les images de base
debian:buster-slim
, et python
sont fréquemment mis à jour, il y a un certain écart entre la sortie des mises à jour de sécurité de Debian et de les transformer en images. Par conséquent, vous devez installer indépendamment les mises à jour de sécurité pour la distribution Linux de base.
Quelles images Docker utilisez-vous pour exécuter du code Python?