Я хотел бы докернизировать программу на 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
Мои вопросы:
Почемуизображение на первом этапе такое большое? Можно ли как-то уменьшить размер? Как выбрать, что установить из пакета pandas?
Почему мой двоичный файл работает нормально в моей системе (Kubuntu 18.10), но я не могу запустить его из alpine:3.4
, если я использую другой образили установить что-нибудь для его запуска?
Какой лучший способ создать минималистичный образ с моим приложением? Один из упомянутых выше или есть другие способы?