Многоступенчатая сборка Docker с использованием flask и postgressql

#python #docker #flask #containers #devops

#python #docker #flask #контейнеры #devops

Вопрос:

Я пытался уменьшить изображение flask postgresql с помощью многоступенчатой сборки docker, но это сбой, потому что он не находит flask app.py . Есть идеи, почему это происходит?

Ошибка:

 web_1  | Usage: flask run [OPTIONS]
web_1  | 
web_1  | Error: The file/path provided (app.py) does not appear to exist.  Please verify the path is correct.  If app is not on PYTHONPATH, ensure the extension is .py
first-web-page_web_1 exited with code 2

  

Файл Dockerfile, который не работает:

 FROM python:3.7-alpine as compile-image

RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

COPY . .
RUN apk update amp;amp; apk add postgresql-dev gcc musl-dev amp;amp; pip install -r requirements.txt

FROM python:3.7-alpine AS build-image

COPY --from=compile-image /opt/venv /opt/venv

# Make sure we use the virtualenv:
ENV PATH="/opt/venv/bin:$PATH"
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
CMD ["flask", "run"]
EXPOSE 5000

  

Рабочий файл Dockerfile, который не является многоступенчатым:

 FROM python:3.7-alpine as build
RUN mkdir /code

WORKDIR /code
COPY requirements.txt /code/
RUN apk update amp;amp; apk add postgresql-dev gcc musl-dev amp;amp; pip install -r requirements.txt

FROM build
COPY --from=build /code .

ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
CMD ["flask", "run"]
EXPOSE 5000
COPY . /code/
  

Размер рабочего образа составляет около 130 МБ после его загрузки в реестр, возможно ли вообще уменьшить его?

Ответ №1:

Здесь многое происходит.

Во-первых, вы обычно используете два контейнера для такого рода проектов: один для базы данных, а другой для веб-приложения. Это имеет несколько преимуществ:

  • Вы можете использовать официальный postgresql образ, а не создавать свой собственный
  • Вы можете обновить один компонент, не отключая другой (приятная особенность, которую вы часто вносите в свое веб-приложение, но хотели бы, чтобы база данных просто оставалась в рабочем состоянии)
  • Вы можете масштабировать свое веб-приложение отдельно от базы данных
  • Вы можете положиться на docker для перезапуска сбойной службы

Что касается вашего вопроса:

Когда вы COPY . . , вы не копируете свое приложение в /opt/venv . Это происходит в корневом каталоге, / . На втором этапе вы делаете это:

 COPY --from=compile-image /opt/venv /opt/venv
  

Вы никогда не копируете свое приложение в конечный образ.

Во-вторых, когда вы это:

 RUN apk update amp;amp; apk add postgresql-dev gcc musl-dev amp;amp; pip install -r requirements.txt
  

Вы не устанавливаете свои зависимости Python в свою виртуальную среду, потому что вы никогда ее не активировали.

Я думаю, вам было бы лучше использовать два отдельных изображения для запуска двух отдельных контейнеров (а затем использовать что-то вроде docker-compose для управления стеком вашего приложения).

Комментарии:

1. Причина, по которой я не хочу иметь 2 изображения, заключается в том, что у меня уже есть запущенный сервер posgress, моя основная задача — уменьшить размер образа docker, на котором установлен postgressql, но спасибо за ваше предложение.

2. Первый этап ставит /opt/venv/bin перед $PATH , поэтому он должен выполняться /opt/venv/bin/pip , который фактически установит вещи в виртуальную среду.

Ответ №2:

Мне удалось уменьшить изображение (с 140 МБ ~ 24 МБ), но не с помощью многоступенчатых сборок, просто удалив зависимости, которые были необходимы для postgresql установки. Если у кого-нибудь есть идея, почему он не работает с многоступенчатым, я был бы признателен.

 FROM python:3.7-alpine

RUN mkdir /code

ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0

ARG BUILD_DEPS="gcc musl-dev postgresql-dev"
ARG RUNTIME_DEPS="libpq"

WORKDIR /code
COPY requirements.txt /code/
RUN apk add --no-cache --virtual .build_deps ${BUILD_DEPS} amp;amp; 
    apk add --no-cache ${RUNTIME_DEPS} amp;amp; 
    pip install --no-cache-dir -r requirements.txt amp;amp; 
    apk del .build_deps 

CMD ["flask", "run"]
EXPOSE 5000
COPY . /code/