UVICORN 在 docker 容器内重新加载不起作用

问题描述 投票:0回答:2

在尝试了网络上几乎所有不同的解决方案后,我仍然遇到在 Docker 容器内热重载 FAST api 应用程序的问题。

我可以看到卷映射正在做它的事情,并且文件在 docker 容器内更新。

控制台日志告诉我 uvicorn 正在监视正确文件夹内的文件。 但我所做的任何更改都不会触发应用程序的重新加载。

我有以下设置:

我的码头工人撰写:

#docker-compose.yml
version: "3"

services:
  app:
    container_name: api
    image: api:latest
    depends_on:
      - mysqldb
    build: 
      context: .
      dockerfile: Dockerfile.dev
      args:
        DEV: "true"
    ports:
      - "8080:8080"
    env_file:
      - .env
    environment:
      - WATCHFILES_FORCE_POLLING=true
      - DEV=1
      - MYSQL_HOSTNAME=mysqldb
      - MYSQL_PORT=3306
    command: uvicorn app.main:app --host 0.0.0.0 --port 8080 --reload --reload-dir /src/app
    volumes:
      - ./app:/src/app
  mysqldb:
    container_name: mysqldb
    image: mysql:latest
    restart: always
    ports:
     - 3307:3306
    environment:
      MYSQL_ROOT_PASSWORD: randompassword
      MYSQL_DATABASE: my-database

我的码头工人组成

#dockerfile.dev
FROM python:3.10-slim-buster

ENV PYTHONUNBUFFERED 1

COPY requirements.txt /
COPY alembic.ini /
COPY migrations /migrations

RUN pip install --upgrade pip setuptools wheel gunicorn uvloop httptools
RUN pip install -r requirements.txt
RUN pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
RUN pip install sentence-transformers 

# Copy the source code to src folder
COPY . /src

ENV PYTHONPATH=/src

EXPOSE 8080

# FOR local dev the startup happens inside the docker-compose with reload options
COPY startup.sh /src/startup.sh
RUN chmod +x /src/startup.sh

CMD ["uvicorn", "app.main:app","--host", "0.0.0.0", "--port", "8080", "--reload"]

我已经尝试了几乎所有可能的重新加载配置。

  • 无需在 docker 文件内运行 uvicorn 命令
  • 重新加载目录为 root (/)、app 和 src/app
  • 没有重新加载目录
  • 用guvicorn服务器代替uvicorn服务器

所以我有点卡住了。 有人可以帮我吗?

docker docker-compose fastapi uvicorn hot-reload
2个回答
0
投票

在修改不同的设置后,我们现在有了一个稳定的重新加载工作区。 uvicorn --reload 语句的问题与卷映射和调用命令的时间点有关。

现在,我不再从 docker compose 文件运行 uvicorn 命令,而是运行一个命令来保持容器处于活动状态:

command: /bin/sh -c "while true; do sleep 30; done"

然后我手动连接容器:

docker exec -it ml_api /bin/bash

然后我可以启动(或手动重新启动)uvicorn(或guvicorn)服务器。重新加载语句现在可以正常工作,如果发生任何重大变化,我可以重新启动 uvicorn,而无需重新启动我的 docker 容器。


0
投票

您的一般方法应该有效,但您可能错误地依赖

PYTHONPATH
,这反过来意味着Python看不到已安装的代码。

按照 Docker docs 中的第 7 点,Dockerfile 中的

ENV
会被 docker-compose 脚本中的任何
environment
禁用。您可以考虑在 Dockerfile 中使用
WORKDIR
,如有必要,在您的 compose 文件中使用 working_dir 来实现类似的结果。

© www.soinside.com 2019 - 2024. All rights reserved.