У меня есть несколько сервисов, которые запускают python 3.7 с flask и требуют всего несколько дополнительных библиотек. Одним из них является psycopg2 для подключения к postgres.
Сама по себе установка psycopg2 в alpine не очень сложная задача, но у меня возникли некоторые проблемы с поиском документации по этому вопросу. Мне удалось получить этот файл докеров, который работает нормально. Самым большим недостатком является то, что он весит около 355 МБ и слишком тяжелый.
Это мой первоначальный файл докеров перед любой оптимизацией:
FROM python:3.7-alpine
ENV PATH /usr/local/bin:$PATH
ENV LANG C.UTF-8
RUN mkdir -p /usr/src/app
COPY requirements.txt /usr/src/app/
RUN apk update \
&& apk add postgresql-dev \
&& apk add --virtual temp1 gcc python3-dev musl-dev \
&& pip install --upgrade pip \
&& pip install psycopg2==2.8.4
RUN pip install -r /usr/src/app/requirements.txt
RUN apk del temp1
COPY . /usr/src/app
WORKDIR /usr/src/app
EXPOSE 6000
ENTRYPOINT ["python3"]
CMD ["-m", "server"]
И мои требования.txt
psycopg2 == 2.8.4
connexion == 1.1.15
python_dateutil == 2.6.0
loguru~=0.4.1
flask~=1.1.2
six~=1.14.0
Werkzeug==0.16.1
pymongo
PyYAML == 5.3
setuptools == 45.1.0
flask_testing == 0.7.1
mo-future>=3
pyparsing==2.3.1
mo_files
pycryptodomex
ldap3
Проведя некоторое тестирование, я обнаружил, что шаги, которые больше всего увеличивают размер изображения:
Вещи, которые я пытался сделать, чтобы уменьшить его размер:
Я постараюсь ответить на эти вопросы:
Первое, что я хотел сделать, это удалить postgresql-dev из контейнера и по-прежнему иметь возможность использовать psycopg2. Единственный файл, который, похоже, отсутствует, это libpq.so.5. Этот файл доступен в alpine package libpq, доступном здесь.
Таким образом, мы можем собрать psycopg2 и сохранить практически все пространство, которое он использовал раньше.
Я попытался свести к минимуму количество шагов в файле докеров, чтобы окончательное изображение было светлее. Добавив соответствующие флаги в pip и apk, мы можем уменьшить объем пространства, используемого для кеша. Кроме того, объявление переменной для группировки всех зависимостей сборки упрощает работу.
Также я определил более тщательно написанный .dockerignore, чтобы сэкономить еще больше места. Использование таких инструментов, как дерево, может помочь вам найти в контейнере ненужные файлы.
Основываясь на этой прекрасной статье, я смог указать пользователя для моего контейнера, у которого не было возможности изменять контейнер.
Это файл докеров, который у меня получился. Он уменьшился с 355 МБ до 135 МБ, что не совсем идеально, но намного лучше.
FROM python:3.7-alpine
ENV PATH /usr/local/bin:$PATH
ENV LANG C.UTF-8
ENV USER=prodUser UID=12345 GID=23456
RUN mkdir -p /usr/src/app
COPY requirements.txt /usr/src/app/
RUN buildDeps='gcc python3-dev musl-dev postgresql-dev' \
&& apk update \
&& apk add --no-cache libpq \
&& apk add --virtual temp1 --no-cache $buildDeps \
&& pip install --no-cache-dir -r /usr/src/app/requirements.txt \
&& apk del temp1
COPY . /usr/src/app
WORKDIR /usr/src/app
RUN addgroup --gid "$GID" "$USER" \
&& adduser \
--disabled-password \
--gecos "" \
--ingroup "$USER" \
--uid "$UID" \
"$USER"
USER $USER
EXPOSE 6000
ENTRYPOINT ["python3"]
CMD ["-m", "server"]
Я все еще новичок в работе с докером, поэтому любые советы или изменения, которые вы предлагаете, приветствуются!
Большое спасибо этому ответчику. Наконец-то я поставил свой контейнер на дорогу.
Не должно быть особой необходимости исправлять идентификаторы пользователей и групп; просто позволить
adduser
выбрать что-то по умолчанию — это нормально. Это разделениеENTRYPOINT
иCMD
на самом деле не имеет смысла, и я, вероятно, поместил бы все вCMD
безENTRYPOINT
.