【问题标题】:Flask running in Docker. Need to rebuild every time在 Docker 中运行的烧瓶。每次都需要重建
【发布时间】:2022-01-10 11:29:50
【问题描述】:

我正在尝试让我的 Flask Docker 构建能够从运行 uWSGI + Nginx 进行生产切换到简单地运行 flask run 进行本地开发。

我有 Flask 在开发模式下运行:

这是我的 Dockerfile:

FROM python:3

RUN apt-get -qq update

RUN apt-get install -y supervisor nginx
RUN pip install uwsgi

# Expose dev port
EXPOSE 5000

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

COPY nginx.conf /etc/nginx/sites-enabled/default

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

WORKDIR /usr/src/app

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

RUN pip install --editable .

CMD [ "supervisord" ]

我正在暴露我从docker-compose.yml 运行的端口 5000:

version: '3'
services:
  web:
    build: ./
    environment:
      DATABASE_URL: postgresql://postgres@db/postgres
      FLASK_APP: app.main
      FLASK_ENV: development
    command: flask run --host=0.0.0.0
    ports:
      - "5000:5000"
    links:
      - db
    volumes:
      - .:/app
  db:
    image: postgres
    restart: always
    ports:
      - 5433:5432
    volumes:
      - data:/var/lib/postgresql/data
volumes:
  data:
    driver: local

我可以在http://0.0.0.0:5000/ 上构建并正常运行它,但如果我在视图或模板中更改任何代码,服务器上不会刷新/重新加载任何内容,我不得不重新构建。

我认为通过在我的 docker-compose 中指定 FLASK_ENV: development 可以启用 Flask 服务器的自动重新加载。关于如何调试的任何想法?

【问题讨论】:

    标签: docker flask docker-compose


    【解决方案1】:

    在主机上调试它,在 Docker 之外。如果您需要访问在 Docker 中运行的数据库,您可以将环境变量(如 MYSQL_HOSTPGHOST)设置为指向 localhost。您根本不需要 root 权限(任何 docker 命令都意味着不受限制的 root 访问权限)。您的 IDE 不会因为您的代码在“其他地方”以不同的文件系统布局运行而感到不安。如果您有远程调试器,则无需遍历 Docker 分界即可访问它。

    一旦它在主机上合理运行并且您的 py.test 测试通过,然后运行 docker build

    (在服务器渲染视图的特殊情况下,您应该能够通过 Flask 调试服务器看到几乎完全相同的内容,而无需在其前面安装 nginx 代理,并且您可以控制安装的库版本通过setup.py 文件中的要求。所以桌面环境会简单得多,你应该能够说服自己它非常接近 Docker 世界中运行的环境。)

    【讨论】:

      【解决方案2】:

      当您从 docker-compose 运行烧瓶应用程序时,它运行的是您在 Dockerfile 中使用 pip install --editable . 安装的版本。问题在于,这不是您在挂载到“/app”的卷中从 Docker 外部编辑的版本(而是/usr/src/app 中与COPY . . 命令不同的版本)。

      Dockerfile 在构建时需要 COPY 和 ADD,而不是运行时,因此为了从实时版本运行 flask run 命令不能从 pip installed 包运行。

      你有几个选择:

      1. pip install 命令移动到 docker-compose command(可能通过调用执行 pip installflask run 的 bash 脚本)。
      2. 运行flask run 命令没有 pip installing 包。如果您在/app 文件夹中,我相信flask 将识别当前文件夹保存代码(给定FLASK_APP 变量),因此pip install 是不必要的。这适用于我遇到相同问题的简单应用程序,但我想如果您有复杂的导入或其他依赖于已安装包的东西,这将不起作用。
      3. 我想如果您协调 /usr/src/app/app 文件夹,以便在构建时 pip install --editable 然后覆盖该文件夹,以便 python 在同一个位置但在本地安装的卷中查找,您可以欺骗它开始工作,但我还没有完全让这个工作......当我这样做时,按照烧瓶日志(docker logs -f web)表明它知道文件何时发生变化,但行为似乎并没有真正改变。我不知道为什么会这样,但我怀疑 pip 对文件夹交换感到不安。

      【讨论】:

        最近更新 更多