Как минимизировать образ докера приложения Python3.7 - PullRequest
0 голосов
/ 17 октября 2019

Я хотел бы докернизировать программу на Python с помощью этого Dockerfile:

FROM python:3.7-alpine

COPY requirements.pip ./requirements.pip

RUN python3 -m pip install --upgrade pip

RUN pip install -U setuptools

RUN apk update

RUN apk add --no-cache --virtual .build-deps gcc python3-dev musl-dev openssl-dev libffi-dev g++ && \
    python3 -m pip install -r requirements.pip --no-cache-dir && \
    apk --purge del .build-deps

ARG APP_DIR=/app

RUN mkdir -p ${APP_DIR} 

WORKDIR ${APP_DIR} 

COPY app . 

ENTRYPOINT [ "python3", "run.py" ]

, и это мой requirements.pip файл:

pysher~=0.5.0

redis~=2.10.6

flake8~=3.5.0

pandas==0.23.4

Из-за панд, образ докераимеет 461 МБ, без панд 131 МБ.

Я думал, как сделать его меньше, поэтому я строю двоичный файл из моего приложения, используя:

pyinstaller run.py --onefile

Он строит 38M двоичный файл. Когда я запускаю его, он работает нормально. Поэтому я создаю образ докера из Dockerfile:

FROM alpine:3.4

ARG APP_DIR=/app
RUN mkdir -p ${APP_DIR}
WORKDIR ${APP_DIR}

COPY app/dist/run run

ENTRYPOINT [ "/bin/sh", "/app/run" ]

По сути, просто скопировал мой двоичный файл run в каталог /app. Выглядит хорошо, изображение имеет только 48,8 МБ. Когда я запускаю контейнер, я получаю сообщение об ошибке:

$ docker run --rm --name myapp myminimalimage:latest
/app/run: line 1: syntax error: unexpected "("

Тогда я подумал, может быть, есть проблема с sh, поэтому я установил bash, поэтому я добавил 3 строки в Dockerfile:

RUN apk update

RUN apk upgrade

RUN apk add bash

Изображение было построено, но при его запуске снова появляется ошибка:

$ $ docker run --rm --name myapp myminimalimage:latest
/app/run: /app/run: cannot execute binary file

Мои вопросы:

  1. Почемуизображение на первом этапе такое большое? Можно ли как-то уменьшить размер? Как выбрать, что установить из пакета pandas?

  2. Почему мой двоичный файл работает нормально в моей системе (Kubuntu 18.10), но я не могу запустить его из alpine:3.4, если я использую другой образили установить что-нибудь для его запуска?

  3. Какой лучший способ создать минималистичный образ с моим приложением? Один из упомянутых выше или есть другие способы?

Ответы [ 2 ]

1 голос
/ 18 октября 2019

Для размеров убедитесь, что вы всегда проходите --no-cache-dir при использовании pip (вы используете его один раз, но не в других случаях). Аналогично, объедините использование apk и убедитесь, что последний шаг - очистить кэш apk, чтобы он никогда не зависал в слое изображения, например, замените три отдельных RUN на RUN apk update && apk upgrade && apk add bash && rm -rf /var/cache/apk/*;достигает того же эффекта в одном слое, который не удерживает кэш apk.

Пример:

FROM python:3.7-alpine

COPY requirements.pip ./requirements.pip

# Avoid pip cache, use consistent command line with other uses, and merge simple layers
RUN python3 -m pip install --upgrade --no-cache-dir pip && \
    python3 -m pip install --upgrade --no-cache-dir setuptools

# Combine update and add into same layer, clear cache explicitly at end
RUN apk update && apk add --no-cache --virtual .build-deps gcc python3-dev musl-dev openssl-dev libffi-dev g++ && \
    python3 -m pip install -r requirements.pip --no-cache-dir && \
    apk --purge del .build-deps && rm -rf /var/cache/apk/*

Не ожидайте, что это сделает много (вы уже использовали--no-cache-dir на большой операции pip), но это что-то. pandas - это огромный монолитный пакет, зависящий от других огромных монолитных пакетов;Есть предел тому, что вы можете сделать здесь.

0 голосов
/ 18 октября 2019

Имейте в виду, что если вы не используете Alpine, вам не понадобится компилятор, поскольку вы можете просто использовать колеса. Это делает все проще ... например, вам не нужно устанавливать, а затем удалять компиляторы. Чуть больше, но ненамного.

(Подробнее о том, почему я не фанат Alpine Linux, смотрите здесь: https://pythonspeed.com/articles/base-image-python-docker-images/)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...