Python container image - это реализация легковесной сборки ЯП Python на базе Astra Linux
Присоединяйтесь к нашим социальным сетям:
- Docker >= 28.1.1 (возможно работает в предыдущих версиях, но мы не можем это гарантировать)
| OS | Python | Status |
|---|---|---|
| ✅ Fully supported | ||
| ✅ Fully supported |
Этот образ предоставляет среду выполнения Python внутри контейнера. Он предназначен для запуска приложений на Python в изолированной среде. Образ содержит только стандартную библиотеку Python и минимальный набор зависимостей. Образ построен на основе отечественной ОС Astra Linux
Для начала работы необходимо установить pre-commit и хуки
$ pip install pre-commit
$ pre-commit --version
pre-commit 4.2.0
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
pre-commit installed at .git/hooks/commit-msg
pre-commit installed at .git/hooks/pre-pushWarning
Чтобы проверить свои изменения, воспользуйтесь командой pre-commit run --all-files.
Чтобы проверить конкретную задачу, воспользуетесь командой pre-commit run <target> --all-files.
Если Вы понимаете что творите и хотите пропустить проверку pre-commit-ом воспользуйтесь --no-verify, пример git commit -m "Добавил изменения и не хочу проверки" --no-verify
Существует несколько способов как можно взаимодействовать со сборкой образа. Благодаря скрипту1 может существовать 3 способа передачи аргумента в Dockerfile:
-
Передача 'примерной' версии. В результате передачи данной строки, скрипт попытается найти точную версии, если таковой нет, то будет возвращена пустая строка
## Export Python version for 1.7.5 $ export PYTHON_VERSION='3.7-astra1.7.5-slim' ## Python build utils image: 126MB docker build \ --progress=plain \ --build-arg python_identity=3.7 \ --build-arg image_version=1.7.5-slim \ -t python:"${PYTHON_VERSION}" \ . .. build ...
-
Передача точной версии
## Export Python version for 1.8.2 $ export PYTHON_VERSION='3.11-astra1.8.2-slim' ## Python build utils image: 141MB docker build \ --progress=plain \ --build-arg python_identity=3.11.2-1+b3 \ --build-arg image_version=1.8.2-slim \ -t python:"${PYTHON_VERSION}" \ . .. build ...
-
Передача ссылки, на заранее собранный из исходников Python
## Export Python version for 1.8.2 $ export PYTHON_VERSION='3.13-astra1.8.2-slim' ## Python build utils image: 198MB docker build \ --progress=plain \ --build-arg python_identity=https://example-registry.com/repository/python/python-v3.13.2-linux-amd64.tar.gz \ --build-arg image_version=1.8.2-slim \ -t python:"${PYTHON_VERSION}" \ . .. build ...
Tip
Проверка доступных версий приложения -
apt show python3-minimal,
apt-cache policy python3-minimal,
apt-cache show python3-minimal
Работа с прокси репозиториями. Логика работы тоже является 'плавающей' т.е. позволяет передавать разный набор параметров для Вашего удобства:
-
Если Вам необходим полный контроль над расположением репозиториев и/или индекс отличается от индекса местоположения прокси репозитория - разрешается использовать полный набор определения прокси
## Export Python version for 1.8.2 $ export PYTHON_VERSION='3.11-astra1.8.2-slim' docker build \ --progress=plain \ --build-arg image_registry=example-container.registry.com/ \ --build-arg pip_registry_index=https://example-registry.com/repository/python-cache-repostory/pypi \ --build-arg pip_registry_url=https://example-registry.com/repository/python-cache-repostory/simple \ --build-arg pip_trusted_host=example-registry.com \ --build-arg python_identity=3.11 \ --build-arg image_version=1.8.2-slim \ -t python:"${PYTHON_VERSION}" \ . .. build ...
-
Если
indexиindex-urlимеют один 'источник', то возможна логика обобщения через переменные## Export Python version for 1.8.2 $ export PYTHON_VERSION='3.11-astra1.8.2-slim' docker build \ --progress=plain \ --build-arg image_registry=example-container.registry.com/ \ --build-arg package_registry_proxy=https://example-registry.com/repository/python-cache-repostory \ --build-arg package_registry_trust_host=example-registry.com \ --build-arg python_identity=3.11 \ --build-arg image_version=1.8.2-slim \ -t python:"${PYTHON_VERSION}" \ . .. build ...
| Имя | Значение по умолчанию | Тип | Описание |
|---|---|---|---|
image_name |
astra | string | Имя образа. |
image_registry |
'' | string | Адрес до реестра образа2. |
image_version |
1.8.2-slim | string | Версия образа. |
pip_registry_index |
'' | string | Имя индекса, который pip будет использовать из списка заранее заданных в конфиге3. |
pip_registry_url |
'' | string | Переопределение основного источника пакетов, откуда pip будет скачивать по умолчанию3. |
pip_trusted_host |
'' | string | Добавляет хост в список доверенных, чтобы pip не проверял SSL-сертификаты при подключении к нему3. |
python_identity |
3.11 | string | Ожидаемая версия Python1. |
Вовремя работы сборки, pip использует env-wrapper который помогает ускорить установку компонентов. Ниже приведена таблица с краткой информацией о переменных, которые МОГУТ использоваться во время сборки И также глобально объявляться в конечном(целевом) образе. Вы можете использовать те или иные переменные для управления собственными сборками, если понимаете что творите
| Название переменной | Значение | Необходимость при сборке контейнера | Необходимость в scratch-образе |
Краткое объяснение переменной |
|---|---|---|---|---|
PIP_BREAK_SYSTEM_PACKAGES=1 |
Включено | Позволяет обновлять системные пакеты через pip |
Обычно не нужна | Позволяет pip изменять пакеты, установленные системным пакетным менеджером (например, apt, apk) |
PIP_DISABLE_PIP_VERSION_CHECK=1 |
Включено | Отключает проверку обновлений pip — ускоряет установку и избегает сетевых запросов |
Полезно, если образ не имеет интернета или нужно избежать предупреждений | Отключает уведомления о том, что есть новая версия pip |
PIP_NO_CACHE_DIR=1 |
Включено | Ускоряет сборку и экономит место — отключает кэширование пакетов | Может сэкономить место | Отключает создание кэша pip (по умолчанию ~/.cache/pip) |
PIP_NO_COMPILE=1 |
Включено | Ускоряет сборку — не генерирует .pyc файлы |
Уменьшает производительность импорта модулей | Отключает компиляцию .py в .pyc, экономя время и место на этапе сборки |
PIP_ROOT_USER_ACTION=ignore |
ignore | Позволяет запускать pip от root без предупреждений |
Используется, если образ работает от root |
Отключает предупреждения при запуске pip от имени root |
PYTHONDONTWRITEBYTECODE=1 |
Включено | Экономит место — не создаёт .pyc файлов |
Ухудшает производительность | Python не будет записывать скомпилированные байт-коды (__pycache__, .pyc), экономя место и время |
PYTHONWARNINGS="ignore:Unverified HTTPS request" |
"ignore:Unverified HTTPS request" |
Полезно при использовании небезопасных источников или внутренних репозиториев | Может понадобиться, если используется pip или python с HTTP(S) |
Подавляет предупреждения о непроверенных HTTPS-запросах (часто связано с самоподписанными SSL-сертификатами) |
Альтернативный способ очистки кеша, чтобы уменьшить размер образа:
FROM python:3.11-astra1.8.2-slim
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
CMD ["python", "app.py"]В результате сборки базового образа идёт наполнение файла /etc/environment. В нём отражены общие переменные, которые могут использоваться в сборочных образах приложений
-
Пример переменных для образа
3.13установленного из удаленного и скомпилированного Python$ cat /etc/environment PYTHON_REVISION=Installed-from-URL BEGIN_BUILD_IN_EPOCH=1746194532 PYTHON_LIB_PATH=/usr/local/lib/python3.13 PYTHON_SITE_PACKAGES=/usr/local/lib/python3.13/site-packages PYTHON_MAJOR_MINOR_PATCH_VERSION=3.13.2 PYTHON_MAJOR_MINOR_VERSION=3.13
-
Пример переменных для образа
3.11из репозиториев Astra Linux$ cat /etc/environment PYTHON_REVISION=3.11.2-1+b3 BEGIN_BUILD_IN_EPOCH=1746191721 PYTHON_LIB_PATH=/usr/lib/python3.11 PYTHON_SITE_PACKAGES=/usr/local/lib/python3.11/dist-packages PYTHON_MAJOR_MINOR_PATCH_VERSION=3.11.2 PYTHON_MAJOR_MINOR_VERSION=3.11
-
Пример переменных для образа
3.7из репозиториев Astra Linux$ cat /etc/environment PYTHON_REVISION=3.7.3-1 BEGIN_BUILD_IN_EPOCH=1746278986 PYTHON_LIB_PATH=/usr/lib/python3.7 PYTHON_SITE_PACKAGES=/usr/local/lib/python3.7/dist-packages PYTHON_MAJOR_MINOR_PATCH_VERSION=3.7.3 PYTHON_MAJOR_MINOR_VERSION=3.7
Для того чтобы начать использовать данный образ, создайте Dockerfile с простыми настройками
FROM python:3.11-astra1.8.2-slim
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD [ "python", "./your-daemon-or-script.py" ]Затем соберите и запустите полученный образ
$ docker build -t my-python-app .
$ docker run -it --rm --name my-running-app my-python-app
...run logic...Для того, чтобы запустить одиночный файл Python-а, Вы можете использовать следующую команду
$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:3.11-astra1.8.2-slim python your-daemon-or-script.py
...run logic...Простой тест:
docker run --rm python:3.11-astra1.8.2-slim python -c "print('Hello from Python')"Данный раздел будет обеспечивать краткие вводные для того, чтобы Вы в дальнейшем могла проектировать свои Scratch сборки, на примере сложносоставного проекта. Все, что демонстрируется, также подкреплено и всеми задействованными скриптами сборочными или специализированными для сборки через scratch. Все манипуляции поделены на определенное количество 'шагов' для которых будут даны краткие комментарии:
-
Первым этапом идёт подготовка окружения, установка зависимостей как системных, так и
pip## Install base project deps # hadolint ignore=DL3042 RUN \ --mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \ --mount=type=bind,source=./requirements.txt,target=/requirements.txt,readonly \ apt-install.sh \ libldap2-dev \ libpq-dev \ libsasl2-dev \ libssl-dev \ iputils-ping \ python3-dev \ build-essential \ ldap-utils \ libfreetype6-dev \ libpq-dev \ libidn2-dev \ ## Set corporative proxy && python-set-proxy.sh \ ## Install project components && pip-env.sh pip install -r /requirements.txt \ && python-rm-cache.sh "${PYTHON_VENV_SITE_PACKAGES}" \ ## Clean cache && apt-clean.sh
-
Второй этап включает в себя компиляцию интерпретатора Python, без компиляции установленных пакетов. Пояснение: компилирование пакетов, может грозить тем, что проект будет не пригоден, т.к. помимо
.pyмогут находится и.cрасширения и при компилировании такой 'солянки' приложение попросту перестанет работать, т.к. не сможет найти ассоциации с другими расширениями. Пример таких расширений которые могут 'сломать' сборку:numpy,pandas,cryptographyи т.д.## Change path to work dir WORKDIR /opt ## Compile and cleanup cpython ## We not compile VENV because this packages include C and multiple another extension # hadolint ignore=DL3003,SC1091 RUN \ --mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \ ## Get build info from env file source /etc/environment \ ## Change path to main python && cd "${PYTHON_LIB_PATH}" \ ## Compile root python && python-compile.sh \ ## Reduce package directory size && PYTHON_VENV_SITE_PACKAGES="$(python3 -c 'import site;print(site.getsitepackages()[0])')" \ && python-remove-unwanted.sh "${PYTHON_VENV_SITE_PACKAGES}" \ && find "${PYTHON_VENV_PATH}" -iname '*.exe' -ls -delete
-
Третьим этапом формируем базовую структуру, которая будет перенесена в
Scratch## Install build components RUN \ ## Directory structure and permissions mkdir -p \ /base/bin \ /base/tmp \ /base/var/tmp \ /base/etc/ssl \ /base/sbin \ /base/root \ /base/usr/lib/ \ "/base${PYTHON_VENV_PATH%/*}" \ /base/usr/src/app \ && chmod 700 /base/root \ && chown root:root /base/root \ && chmod 1777 /base/tmp /base/var/tmp \ ## UID and GID && echo 'root:x:0:' > /base/etc/group \ && echo 'root:x:0:0:root:/root:/sbin/nologin' > /base/etc/passwd \ ## Nologin binary && echo 'int main() { return 1; }' > nologin.c \ && gcc -Os -no-pie -static -std=gnu99 -s -Wall -Werror -o /base/sbin/nologin nologin.c
-
Четвертым этапом происходит перенос основной файловой структуры, для оптимальной и минимальной работы приложения
## Copy depended binary # hadolint ignore=SC1091 RUN \ --mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \ ## Get python version source /etc/environment \ ## Execute transfer ldd /bin && copy-bin.sh \ --prefix "/base" \ --ldd "/bin/dumb-init" \ --links "/bin:/sbin:/usr/bin:/usr/sbin" \ ## Execute transfer ldd /usr/bin && copy-bin.sh \ --prefix "/base" \ --ldd "/usr/bin/python${PYTHON_MAJOR_MINOR_VERSION}" \ --links "/bin:/sbin:/usr/bin:/usr/sbin" \ ## Copy compiled python venv && cp -R "${PYTHON_VENV_PATH}" "/base${PYTHON_VENV_PATH%/*}" \ ## Copy compiled python && cp -R "${PYTHON_LIB_PATH}" "/base/usr/lib/" \ ## Copy shared objects && copy-lib.sh /base/lib/x86_64-linux-gnu/ \ ## Can read host files for FQDN /usr/lib/x86_64-linux-gnu/libnss_files \ ## PYTHON critical shared objects /usr/lib/libgost \ /usr/lib/x86_64-linux-gnu/libquadmath \ ... list of libs ... ## Cleanup from deduplicates transfer directory && dedup-clean.sh /base/usr/
-
Пятый - это побочный этап, здесь можно раздать необходимые права на рабочий путь и перенести необходимые рабочие файлы
## Transfer base project component COPY lib/ /base/usr/src/app/lib/ ## Remove extra write permissions RUN \ find /base/usr/src/app -type f -print0 | xargs -0 chmod 644 \ && find /base/usr/src/app -type d -print0 | xargs -0 chmod 755
-
Шестой этап - это слой отладки. Необходимая мера, для того чтобы в случае неполадок или ошибок, мы могли собрать образ с
docker build --target debug-stageи вывести отладочную информацию о вызовах при помощи, например,wrapper-lib.shFROM base-stage AS debug-stage RUN \ --mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \ ## Install debug tools apt-install.sh \ strace \ ltrace \ gdb \ tcpdump \ procps \ net-tools \ jq \ xmlstarlet \ ## Clean cache && apt-clean.sh ## Set work directory WORKDIR /usr/src/app ## Transfer base project component COPY lib/ lib/
-
Седьмой этап - интеграция со
Scratchобразом. Т.к. там нет ничего, то необходимо позаботиться о том, чтобы существовали необходимые пути, переменные. Также, т.к. установка пакетов была без.pycрасширения, то на наши плечи ложится такая операция как прогрев кеша. Пользуясь небольшой хитростью, мы временно монтируемbashкакsh, чтобы обойти ограничение, при которомDockerссылается, без явного указания на оболочку черезSHELL, на/bin/shи выполняем желаемый список команд# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Final image # # Third stage, compact optimize layer # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # FROM scratch COPY --from=base-stage /base/ / ENV PYTHON_VENV_PATH='/usr/local/lib/python-venv' ## Add venv into path ENV \ PATH="${PYTHON_VENV_PATH}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \ LANG=C.UTF-8 ## Set work directory WORKDIR /usr/src/app ## Little trick, we just mounting shell to provide cache warmup RUN \ --mount=type=bind,from=base-stage,source=/usr/bin/bash,target=/bin/sh,readonly \ --mount=type=bind,from=base-stage,source=/usr/lib/x86_64-linux-gnu/libtinfo.so.6,target=/usr/lib/x86_64-linux-gnu/libtinfo.so.6,readonly \ gunicorn --help \ && netaddr --help \ && normalizer --help \ && f2py -h \ && flask --help \ && fonttools --help \ && numpy-config --help ENTRYPOINT [ "dumb-init", "--" ] CMD [ "python3" ]
Полный Dockerfile:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Base image #
# First stage, prepare environment #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
FROM python:3.11-astra1.8.2 AS base-stage
SHELL [ "/bin/bash", "-exo", "pipefail", "-c" ]
## Redefined DEFAULT args
ARG package_registry_proxy
ARG package_registry_trust_host
## Install base project deps
# hadolint ignore=DL3042
RUN \
--mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \
--mount=type=bind,source=./requirements.txt,target=/requirements.txt,readonly \
apt-install.sh \
libldap2-dev \
libpq-dev \
libsasl2-dev \
libssl-dev \
iputils-ping \
python3-dev \
build-essential \
ldap-utils \
libfreetype6-dev \
libpq-dev \
libidn2-dev \
## Set corporative proxy
&& python-set-proxy.sh \
## Install project components
&& pip-env.sh pip install -r /requirements.txt \
&& python-rm-cache.sh "${PYTHON_VENV_SITE_PACKAGES}" \
## Clean cache
&& apt-clean.sh
## Change path to work dir
WORKDIR /opt
## Compile and cleanup cpython
## We not compile VENV because this packages include C and multiple another extension
# hadolint ignore=DL3003,SC1091
RUN \
--mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \
## Get build info from env file
source /etc/environment \
## Change path to main python
&& cd "${PYTHON_LIB_PATH}" \
## Compile root python
&& python-compile.sh \
## Reduce package directory size
&& PYTHON_VENV_SITE_PACKAGES="$(python3 -c 'import site;print(site.getsitepackages()[0])')" \
&& python-remove-unwanted.sh "${PYTHON_VENV_SITE_PACKAGES}" \
&& find "${PYTHON_VENV_PATH}" -iname '*.exe' -ls -delete
## Install build components
RUN \
## Directory structure and permissions
mkdir -p \
/base/bin \
/base/tmp \
/base/var/tmp \
/base/etc/ssl \
/base/sbin \
/base/root \
/base/usr/lib/ \
"/base${PYTHON_VENV_PATH%/*}" \
/base/usr/src/app \
&& chmod 700 /base/root \
&& chown root:root /base/root \
&& chmod 1777 /base/tmp /base/var/tmp \
## UID and GID
&& echo 'root:x:0:' > /base/etc/group \
&& echo 'root:x:0:0:root:/root:/sbin/nologin' > /base/etc/passwd \
## Nologin binary
&& echo 'int main() { return 1; }' > nologin.c \
&& gcc -Os -no-pie -static -std=gnu99 -s -Wall -Werror -o /base/sbin/nologin nologin.c
## Copy depended binary
# hadolint ignore=SC1091
RUN \
--mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \
## Get python version
source /etc/environment \
## Execute transfer ldd /bin
&& copy-bin.sh \
--prefix "/base" \
--ldd "/bin/dumb-init" \
--links "/bin:/sbin:/usr/bin:/usr/sbin" \
## Execute transfer ldd /usr/bin
&& copy-bin.sh \
--prefix "/base" \
--ldd "/usr/bin/python${PYTHON_MAJOR_MINOR_VERSION}" \
--links "/bin:/sbin:/usr/bin:/usr/sbin" \
## Copy compiled python venv
&& cp -R "${PYTHON_VENV_PATH}" "/base${PYTHON_VENV_PATH%/*}" \
## Copy compiled python
&& cp -R "${PYTHON_LIB_PATH}" "/base/usr/lib/" \
## Copy shared objects
&& copy-lib.sh /base/lib/x86_64-linux-gnu/ \
## Can read host files for FQDN
/usr/lib/x86_64-linux-gnu/libnss_files \
## PYTHON critical shared objects
/usr/lib/libgost \
/usr/lib/x86_64-linux-gnu/libquadmath \
/usr/lib/x86_64-linux-gnu/libbfd-2.40-system \
/usr/lib/x86_64-linux-gnu/libctf \
/usr/lib/x86_64-linux-gnu/libgmp \
/usr/lib/x86_64-linux-gnu/libjansson \
/usr/lib/x86_64-linux-gnu/libliboqs \
/usr/lib/x86_64-linux-gnu/liboqs \
/usr/lib/x86_64-linux-gnu/libsframe \
/usr/lib/x86_64-linux-gnu/libuuid \
/usr/lib/x86_64-linux-gnu/libgcc_s \
/usr/lib/x86_64-linux-gnu/libffi \
/usr/lib/x86_64-linux-gnu/liblzma \
/usr/lib/x86_64-linux-gnu/libexpat \
/usr/lib/x86_64-linux-gnu/libbz2 \
/usr/lib/x86_64-linux-gnu/libhogweed \
/usr/lib/x86_64-linux-gnu/libnettle \
/usr/lib/x86_64-linux-gnu/libtasn1 \
/usr/lib/x86_64-linux-gnu/libunistring \
/usr/lib/x86_64-linux-gnu/libidn2 \
/usr/lib/x86_64-linux-gnu/libpq \
/usr/lib/x86_64-linux-gnu/libp11-kit \
/usr/lib/x86_64-linux-gnu/libresolv \
/usr/lib/x86_64-linux-gnu/libkeyutils \
/usr/lib/x86_64-linux-gnu/libgnutls \
/usr/lib/x86_64-linux-gnu/liblber-2.5 \
/usr/lib/x86_64-linux-gnu/libkrb5 \
/usr/lib/x86_64-linux-gnu/libkrb5support \
/usr/lib/x86_64-linux-gnu/libk5crypto \
/usr/lib/x86_64-linux-gnu/libcom_err \
/usr/lib/x86_64-linux-gnu/libzstd \
/usr/lib/x86_64-linux-gnu/libgssapi_krb5 \
/usr/lib/x86_64-linux-gnu/librt \
/usr/lib/x86_64-linux-gnu/libssl \
/usr/lib/x86_64-linux-gnu/libcrypto \
/usr/lib/x86_64-linux-gnu/libcrypt \
/usr/lib/x86_64-linux-gnu/libstdc++ \
/usr/lib/x86_64-linux-gnu/libc \
/usr/lib/x86_64-linux-gnu/libpthread \
/usr/lib/x86_64-linux-gnu/libm \
/usr/lib/x86_64-linux-gnu/libdl \
/usr/lib/x86_64-linux-gnu/libz \
/usr/lib/x86_64-linux-gnu/libldap-2.5 \
/usr/lib/x86_64-linux-gnu/libsasl2 \
## Cleanup from deduplicates transfer directory
&& dedup-clean.sh /base/usr/
## Transfer base project component
COPY lib/ /base/usr/src/app/lib/
## Remove extra write permissions
RUN \
find /base/usr/src/app -type f -print0 | xargs -0 chmod 644 \
&& find /base/usr/src/app -type d -print0 | xargs -0 chmod 755
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Debug image #
# Second stage, install debug tools #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
FROM base-stage AS debug-stage
RUN \
--mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \
## Install debug tools
apt-install.sh \
strace \
ltrace \
gdb \
tcpdump \
procps \
net-tools \
jq \
xmlstarlet \
## Clean cache
&& apt-clean.sh
## Set work directory
WORKDIR /usr/src/app
## Transfer base project component
COPY lib/ lib/
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Final image #
# Third stage, compact optimize layer #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
FROM scratch
COPY --from=base-stage /base/ /
## Set base label
LABEL \
maintainer="Vladislav Avdeev" \
organization="NGRSoftlab"
ENV PYTHON_VENV_PATH='/usr/local/lib/python-venv'
## Add venv into path
ENV \
PATH="${PYTHON_VENV_PATH}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
LANG=C.UTF-8
## Set work directory
WORKDIR /usr/src/app
## Little trick, we just mounting shell to provide cache warmup
RUN \
--mount=type=bind,from=base-stage,source=/usr/bin/bash,target=/bin/sh,readonly \
--mount=type=bind,from=base-stage,source=/usr/lib/x86_64-linux-gnu/libtinfo.so.6,target=/usr/lib/x86_64-linux-gnu/libtinfo.so.6,readonly \
gunicorn --help \
&& netaddr --help \
&& normalizer --help \
&& f2py -h \
&& flask --help \
&& fonttools --help \
&& numpy-config --help
ENTRYPOINT [ "dumb-init", "--" ]
CMD [ "python3" ]Добавочная ситуация, при которой в существующий Scratch необходимо добавить пакеты
-
Первым этапом устанавливаем пакет в отдельную директорию, которая послужит дальнейшим 'донором' для дополнения подготовленного заранее
scratchобраза. Здесь показана связка установки пакета из репозиторияGitlab-a# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Base image # # First stage, prepare environment # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # FROM python:3.11-astra1.8.2-slim AS base-stage SHELL [ "/bin/bash", "-exo", "pipefail", "-c" ] # hadolint ignore=DL3013,DL3042 RUN \ --mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \ apt-install.sh git \ && pip-env.sh pip install setuptools \ && pip-env.sh pip install \ --prefix=/additional-package \ "git+https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/python/package-lib.git"
-
Вторым этапом, мы дополняем подготовленный
scratchобраз недостающим пакетов по пути нахождения предыдущих пакетов(в данном случае путь будет/usr/local/lib/python-venv/), наполняем недостающими файлами, необходимыми для работы приложения, и объявляем команду его запуска# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # Final image # # Third stage, compact optimize layer # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # FROM python-scratch-prepared-bundle:1.0.0 COPY --from=base-stage /additional-package/ /usr/local/lib/python-venv/ WORKDIR /usr/src/app COPY --chmod=644 ./app.py ./app.py COPY --chmod=755 lib/ lib/ COPY --chmod=755 etc/ etc/ EXPOSE 5052 CMD ["gunicorn", "--certfile", "etc/service.crt", "--keyfile", "etc/service.key", "-b", "0.0.0.0:5052", "--timeout", "180", "app:create_app()"]
Полный Dockerfile:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Base image #
# First stage, prepare environment #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
FROM python:3.11-astra1.8.2-slim AS base-stage
SHELL [ "/bin/bash", "-exo", "pipefail", "-c" ]
# hadolint ignore=DL3013,DL3042
RUN \
--mount=type=bind,source=./scripts,target=/usr/local/sbin,readonly \
apt-install.sh git \
&& pip-env.sh pip install setuptools \
&& pip-env.sh pip install \
--prefix=/additional-package \
"git+https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/python/package-lib.git"
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Final image #
# Third stage, compact optimize layer #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
FROM python-scratch-prepared-bundle:1.0.0
COPY --from=base-stage /additional-package/ /usr/local/lib/python-venv/
WORKDIR /usr/src/app
COPY --chmod=644 ./app.py ./app.py
COPY --chmod=755 lib/ lib/
COPY --chmod=755 etc/ etc/
EXPOSE 5052
CMD ["gunicorn", "--certfile", "etc/service.crt", "--keyfile", "etc/service.key", "-b", "0.0.0.0:5052", "--timeout", "180", "app:create_app()"]Возможно, можно обойтись иными способами, например компиляция приложения Python
-
PyInstaller$ pip install pyinstaller $ pyinstaller --onefile --add-data 'venv/lib/python3.11/site-packages;pandas' app.py ...compiling binary...
-
PEX(Python EXecutable)$ pex pandas -o app.pex -m app ...prepared app.pex file...
Дополнительно можно изучить источники вдохновения4
Лого для проекта создано при помощи aasvg проекта. Вы можете создать такое же и/или модифицировать имеющееся. Для этого воспользуйтесь сайтом или установите figlet. Если Вы используете способ с установкой figlet, то вдобавок необходимо сказать необходимый шрифт, например я использую Doom. Далее, необходимо воспользоваться aasvg и конвертировать ascii арт в svg. Обратите внимание - по умолчанию будет svg в красном цвете, чтобы изменить цвет, необходимо изменить его определение тут
$ curl 'http://www.figlet.org/fonts/doom.flf' -o /usr/share/figlet/doom.flf
$ curl 'http://www.figlet.org/fonts/larry3d.flf' -o /usr/share/figlet/larry3d.flf
$ figlet -f doom 'Python'
______ _ _
| ___ \ | | | |
| |_/ / _| |_| |__ ___ _ __
| __/ | | | __| '_ \ / _ \| '_ \
| | | |_| | |_| | | | (_) | | | |
\_| \__, |\__|_| |_|\___/|_| |_|
__/ |
|___/
$ aasvg --source --embed < ./docs/ascii.txt > docs/images/logo.svg
Питоновый Петухон под авторством qwen.ai.
|
Footnotes
-
🛠️ За счёт скрипта
python-install-approximately.shнас может не волновать полная версия Python, мы можем передавать лишь приблизительно желаемую версию, а скрипт позаботится чтобы была выбрана последняя и актуальная из списка ↩ ↩2 -
🛠️ Например можно использовать свой приватный реестр образов:
--build-arg image_registry=my-container-registry:1111/↩ -
🛠️ За счёт скрипта
python-set-proxy.shмы можем пользоваться и другим набором аргументов, таких как:package_registry_proxyиpackage_registry_trust_host↩ ↩2 ↩3 -
🛠️ Статическое Python приложение в образе контейнера на базе scratch ↩
