#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/