python:3.8-slim-buster
قراءة ملف Dockerfile
▍ الصورة الأساسية
لنبدأ بالصورة الأساسية:
FROM debian:buster-slim
اتضح أن الصورة الأساسية
python:3.8-slim-busterهي Debian GNU / Linux 10 ، الإصدار الثابت الحالي من Debian ، والمعروف أيضًا باسم Buster (تمت تسمية إصدارات Debian على اسم شخصيات من Toy Story). باستر ، إذا كان أي شخص مهتم ، كلب آندي.
إذن ، في قلب الصورة التي نهتم بها هو توزيع Linux ، والذي يضمن تشغيله المستقر. يتم إصدار إصلاحات الأخطاء بشكل دوري لهذا التوزيع. يحتوي المتغير على
slimحزم مثبتة أقل من المتغير العادي. هناك ، على سبيل المثال ، لا يوجد مجمعين.
متغيرات البيئة
الآن دعونا نلقي نظرة على متغيرات البيئة. الأول يضمن أن يتم إضافته في
/usr/local/binأقرب وقت ممكن إلى $PATH.
# python, ,
ENV PATH /usr/local/bin:$PATH
تم تصميم الصورة بحيث يتم تثبيت Python بتنسيق
/usr/local. نتيجة لذلك ، يضمن هذا البناء استخدام الملفات التنفيذية المثبتة بشكل افتراضي.
بعد ذلك ، دعنا نلقي نظرة على إعدادات اللغة:
# http://bugs.python.org/issue19846
# > "LANG=C" Linux * Python 3*, .
ENV LANG C.UTF-8
بقدر ما أعرف ، فإن Python 3 الحديثة ، بشكل افتراضي ، وبدون هذا الإعداد ، تستخدم UTF-8. لذلك لست متأكدًا مما إذا كان هذا السطر مطلوبًا في Dockerfile المعني هذه الأيام.
يوجد أيضًا متغير بيئة يحتوي على معلومات حول إصدار Python الحالي:
ENV PYTHON_VERSION 3.8.5
يوجد أيضًا متغير بيئة مرتبط بـ GPG في Dockerfile ، والذي يستخدم للتحقق من كود مصدر Python الذي تم تحميله.
▍ تبعيات وقت التشغيل
تحتاج Python إلى بعض الحزم الإضافية لتعمل:
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
netbase \
&& rm -rf /var/lib/apt/lists/*
الحزمة الأولى
ca-certificatesتحتوي على قائمة شهادات CA القياسية. يستخدم المتصفح شيئًا مشابهًا للتحقق من صحة العناوين . يسمح هذا لـ Python wgetوالأدوات الأخرى بالتحقق من صحة الشهادات التي توفرها الخوادم.
الحزمة الثانية ،
netbaseالتي تقوم بالتثبيت في /etcعدة ملفات ، ضرورية لتكوين تعيين أسماء معينة لمنافذ وبروتوكولات معينة. على سبيل المثال ، فهي /etc/servicesمسؤولة عن تكوين مراسلات أسماء الخدمة ، مثل https، مع أرقام المنافذ. في هذه الحالة ، هو 443/tcp.
▍ تثبيت بايثون
يتم الآن تثبيت مجموعة أدوات الترجمة. وبالتحديد ، يتم تنزيل مصدر Python وترجمته ، وبعد ذلك يتم إلغاء تثبيت حزم دبيان غير الضرورية:
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
هناك الكثير مما يحدث هنا ، ولكن أهم شيء هو هذا:
- تم تثبيت Python في
/usr/local. - تتم إزالة كافة ملفات .pyc.
- الحزم ، على وجه الخصوص -
gccوغيرها من النوع المطلوب لتجميع Python ، تتم إزالتها بعد أن لم تعد هناك حاجة إليها.
نظرًا لحقيقة أن كل هذا يحدث بأمر واحد
RUN، ونتيجة لذلك ، لا يتم تخزين المترجم في أي من الطبقات ، مما يساعد في الحفاظ على حجم صورة مضغوط.
هنا يمكنك ملاحظة أن بايثون تحتاج إلى مكتبة لتجميعها
libbluetooth-dev. بدا هذا غير عادي بالنسبة لي ، لذلك قررت اكتشافه. كما اتضح ، يمكن لـ Python إنشاء مآخذ Bluetooth ، ولكن فقط إذا تم تجميعها باستخدام هذه المكتبة.
▍ إعداد ارتباط رمزي
الخطوة التالية
/usr/local/bin/python3هي تعيين ارتباط رمزي /usr/local/bin/python، والذي يسمح باستدعاء بايثون بطرق مختلفة:
# ,
RUN cd /usr/local/bin \
&& ln -s idle3 idle \
&& ln -s pydoc3 pydoc \
&& ln -s python3 python \
&& ln -s python3-config python-config
▍ تثبيت النقطة
مدير الحزم
pipلديه جدول إصدار خاص به يختلف عن جدول إصدار Python. على سبيل المثال ، يقوم Dockerfile هذا بتثبيت Python 3.8.5 ، الذي تم إصداره في يوليو 2020. وتم إصدار النقطة 20.2.2 في أغسطس ، بعد إصدار Python ، ولكن تم تصميم Dockerfile لتثبيت إصدار جديد 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
بعد الانتهاء من هذه العمليات ، كما في السابق ، يتم حذف جميع ملفات .pyc.
▍ نقطة دخول الصورة
نتيجة لذلك ، يتم تحديد نقطة الدخول إلى الصورة في Dockerfile:
CMD ["python3"]
باستخدام
CMDبدلاً من ذلك ، ENTRYPOINTمن خلال تشغيل الصورة ، يمكننا الوصول إلى 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.
>>>
ولكن ، إذا لزم الأمر ، يمكنك تحديد ملفات أخرى قابلة للتنفيذ عند بدء الصورة:
$ docker run -it python:3.8-slim-buster bash
root@280c9b73e8f9:/#
النتيجة
هذا ما تعلمناه من تحليل ملف Dockerfile الرسمي لصورة Python
slim-buster.
▍ الصورة تتضمن بايثون
على الرغم من أن هذا قد يبدو واضحًا ، إلا أنه يجدر الانتباه إلى كيفية تضمين Python في الصورة بالضبط. وهي يتم ذلك عن طريق تثبيته في ملف
/usr/local.
أحيانًا يرتكب المبرمجون الذين يستخدمون هذه الصورة نفس الخطأ ، وهو إعادة تثبيت نسخة دبيان من Python:
FROM python:3.8-slim-buster
# :
RUN apt-get update && apt-get install python3-dev
عند تشغيل هذا الأمر ،
RUNسيتم تثبيت Python مرة أخرى ، ولكن /usrليس بتنسيق /usr/local. ولن يكون هذا عادةً إصدار Python المثبت في /usr/local. وربما لا يحتاج المبرمج الذي استخدم ملف Docker أعلاه إلى نسختين مختلفتين من Python في نفس الصورة. هذا هو السبب الرئيسي للارتباك.
وإذا كان شخص ما يحتاج حقًا إلى نسخة دبيان من Python ، فسيكون من الأفضل استخدامه كصورة أساسية
debian:buster-slim.
▍ تتضمن الصورة أحدث إصدار من النقطة
على سبيل المثال ، كان أحدث إصدار من Python 3.5 في نوفمبر 2019 ، لكن صورة Docker
python:3.5-slim-busterتتضمن الصورة pipالتي صدرت في أغسطس 2020. هذا (عادةً) جيد ، لأنه يعني أن لدينا أحدث إصلاحات للأخطاء وتحسينات في الأداء. هذا يعني أيضًا أنه يمكننا الاستفادة من دعم خيارات العجلات الأحدث.
▍ تتم إزالة كافة ملفات .pyc من الصورة
إذا كنت ترغب في تسريع إقلاع النظام قليلاً ، يمكنك بشكل مستقل تجميع الكود المصدري للمكتبة القياسية بتنسيق .pyc. يتم ذلك باستخدام الوحدة النمطية compileall .
لا تقوم الصورة بتثبيت تحديثات أمان دبيان
على الرغم من أن الصور قاعدة
debian:buster-slim، و pythonيتم تحديثها بشكل متكرر، هناك فجوة معينة بين الافراج عن التحديثات الأمنية ديبيان وتحويلها إلى صور. لذلك ، تحتاج إلى تثبيت تحديثات الأمان بشكل مستقل لتوزيع Linux الأساسي.
ما هي صور Docker التي تستخدمها لتنفيذ كود Python؟
