【问题标题】:Flask not autoreloading inside container when code changes in bind mount directory当绑定挂载目录中的代码更改时,Flask 不会在容器内自动重新加载
【发布时间】:2021-11-08 16:55:32
【问题描述】:

我有一个 Dockerfile,我用它来为 Flask 应用程序创建一个容器。它在一个子目录中,因为我有多个 Dockerfile 和 docker-compose 文件,我不喜欢它们弄乱项目的根目录。

在本地开发时,我想使用 Docker bind mount 将本地目录挂载到容器中,覆盖现有目录。这将允许 Flask 注意到文件更改并重新加载开发服务器,而无需重新启动 Docker 容器。

我正在使用以下命令运行容器:

docker-compose -p myproject -f docker/docker-compose.dev.yml up

绑定装载在此设置下工作

docker/Dockerfile.dev

# setup...

WORKDIR /app
COPY . /app # To allow the container to start successfully, before the bind mount is mounted

docker/docker-compose.dev.yml

services:
  api:
    build:
      context: ..
      dockerfile: ./docker/Dockerfile.dev
    volumes:
      - ..:/app
    // And a bunch of other setup stuff and services

我关注this helpful tutorial 帮助我的容器瘦身,并采用了 Pipenv。它推荐了一个稍微不同的设置,我的容器创建一个用户而不是以 root 运行所有东西。所以我现在有这个失败了:

docker/Dockerfile.dev

# setup...

RUN useradd --create-home appuser
WORKDIR /home/appuser
USER appuser

COPY . .

docker/docker-compose.dev.yml

services:
  api:
    build:
      context: ..
      dockerfile: ./docker/Dockerfile.dev
    volumes:
      - ..:/home/appuser
    // And a bunch of other setup stuff and services

虽然应用程序成功启动,因为我已使用 COPY 命令将所有内容复制到位,但当我更改主机目录中的文件时,服务器不会重新加载。当我使用此命令打开外壳时:

docker run --env-file .env --entrypoint bash --network flasknetwork -v $(PWD):/home/appuser -ti api

然后绑定挂载当然会按预期出现,在容器中隐藏appuser 的主目录。

我不明白这两种设置有什么不同。使用docker-compose 启动容器时,如何让绑定挂载再次工作?

【问题讨论】:

  • 您能否使用基于主机的 Python 虚拟环境进行日常开发,而不是试图说服 Docker 成为实时重载环境?
  • 不使用 Docker 意味着开发人员需要在他们的系统上设置和运行 Postgres(包括各种扩展)。开发人员还需要手动运行 Redis 和工作进程。因此,尽管有可能,但 Docker 提供了更简单的开发体验。幸运的是,我又让它工作了!
  • 您可以将 Docker 用于所有这些基础架构部分,但为应用程序使用虚拟环境。 docker-compose up -d postgres redis 或类似的东西会启动特定的依赖关系,然后你可以配置你的基于主机的应用程序指向他们发布的ports:
  • 那行得通,是的。与当前的设置相比,需要这个额外的步骤有什么好处,您只需执行docker-compose up 并且您离开了吗?
  • 您将拥有一个实际的本地开发环境;您无需依赖 Docker 的卷挂载机制即可将主机文件系统中的内容正确同步到容器中(也就是说,它避免了问题中的问题)。

标签: docker flask docker-compose


【解决方案1】:

所以问题毕竟不是绑定挂载。我使用了docker inspect api,发现挂载按预期工作:

"Mounts": [
    {
        "Type": "bind",
        "Source": "/Users/myuser/src/project",
        "Destination": "/home/appuser",
        "Mode": "rw",
        "RW": true,
        "Propagation": "rprivate"
    }
],

所以我查找了Flask autoreloading,并记得它仅在FLASK_ENV 设置为development 时才有效。当我四处移动时,此设置已被删除,并且我没有将其添加回来。所以应用程序在生产模式下运行,因此不会自动重新加载。

【讨论】:

    猜你喜欢
    • 2018-02-10
    • 1970-01-01
    • 2013-04-27
    • 2014-06-17
    • 2017-09-12
    • 2018-12-13
    • 2013-04-05
    • 2019-09-02
    相关资源
    最近更新 更多