【问题标题】:Docker multi stage build with flask and postgressql使用 flask 和 postgresql 构建 Docker 多阶段
【发布时间】:2020-09-11 21:13:59
【问题描述】:

我一直在尝试使用 docker multistage build 使 flask+postgresql 的图像更小,但它崩溃了,因为它没有找到 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 && apk add postgresql-dev gcc musl-dev && 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 && apk add postgresql-dev gcc musl-dev && 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/

上传到注册表后工作映像的大小约为 130Mb,是否可以将其缩小?

【问题讨论】:

    标签: python docker flask containers devops


    【解决方案1】:

    这里发生了很多事情。

    首先,您通常会为此类项目使用两个容器:一个用于数据库,一个用于 web 应用程序。这有几个优点:

    • 您可以使用官方postgresql 图片,而不是自己滚动
    • 您可以在不关闭另一个组件的情况下升级一个组件(您的一项不错的功能是频繁更改您的 Web 应用程序,但希望数据库保持正常运行)
    • 您可以独立于数据库扩展您的 web 应用
    • 您可以依靠 docker 重新启动失败的服务

    关于你的问题:

    当您COPY . . 时,您不会将您的应用程序复制到/opt/venv。它将进入根目录/。在你的第二阶段,你这样做:

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

    您永远不会将您的应用复制到最终图像中。

    其次,当你这样做时:

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

    您没有将 Python 依赖项安装到虚拟环境中,因为您从未激活过它。

    我认为您最好使用两个单独的图像来启动两个单独的容器(然后使用类似 docker-compose 的东西来管理您的应用程序堆栈)。

    【讨论】:

    • 我不想有 2 个图像的原因是因为我已经有一个正在运行的 posgress 服务器,我的主要重点是降低具有 postgressql installend 的 docker 图像的大小,但是谢谢为您的建议。
    • 第一阶段将/opt/venv/bin放在$PATH的前面,所以它应该运行/opt/venv/bin/pip,这实际上会将东西安装到虚拟环境中。
    【解决方案2】:

    我已经设法使图像更小(从 140MiB 到 24MiB),但不是通过多阶段构建,只需删除安装 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} && \
        apk add --no-cache ${RUNTIME_DEPS} && \
        pip install --no-cache-dir -r requirements.txt && \
        apk del .build_deps 
    
    CMD ["flask", "run"]
    EXPOSE 5000
    COPY . /code/
    
    

    【讨论】:

      猜你喜欢
      • 2023-03-18
      • 1970-01-01
      • 2020-07-13
      • 2022-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      相关资源
      最近更新 更多