Docker 容器崩溃:/bin/sh: 1: [uvicorn,: 未找到

Sum*_*wal 5 python docker fastapi

我是 Docker 新手,正在尝试 Dockerize 我的 FastAPI 应用程序。首先我创建了一个 Dockerfile:

FROM python:3.9.9

WORKDIR /usr/src/app

COPY requirements.txt ./

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

COPY . .

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Run Code Online (Sandbox Code Playgroud)

然后运行以下命令:

docker build -t fastapi .
Run Code Online (Sandbox Code Playgroud)

命令成功运行。

之后我创建了以下 docker-compose.yml:

version: "3"
services: 
  api:
    build: .
    ports:
      - 8000:8000
    env_file:
         ./.env
Run Code Online (Sandbox Code Playgroud)

然后运行以下命令:

docker-compose up -d
Run Code Online (Sandbox Code Playgroud)

跑成功:

    Network fastapi_default  Created                              0.7s 
 - Container fastapi_api_1  Started 
Run Code Online (Sandbox Code Playgroud)

然后为了检查它是否正常运行,我运行了以下命令:

docker ps -a
Run Code Online (Sandbox Code Playgroud)

它显示容器在创建后几秒钟就退出了。

然后我运行了这个命令:

docker logs fastapi_api_1
Run Code Online (Sandbox Code Playgroud)

它说:

/bin/sh: 1: [uvicorn,: not found
Run Code Online (Sandbox Code Playgroud)

不知道是什么原因。尝试了我在网上找到的一些解决方案,但没有任何效果。我的requirements.txt 文件中确实有uvicorn。

我们将提供帮助。如果需要更多信息,请告诉我。

rzl*_*vmp 5

注意:您不需要docker build -t fastapi .手动执行。Docker-compose 会为你做这件事(因为你设置了build: .)但是!您必须运行带参数 ( )up的命令来强制重建映像,即使映像存在--builddocker-compose up --build

\n

关于你的问题:

\n

这是一篇关于和的非常好的文章(还有一篇RUNENTRYPOINTCMD

\n

以下是 的三种形式CMD

\n
\n
    \n
  • CMD ["executable","param1","param2"] (exec 形式,首选)
  • \n
  • CMD ["param1","param2"](以 exec 形式为 ENTRYPOINT 设置附加默认参数)
  • \n
  • CMD命令param1 param2(shell形式)
  • \n
\n
\n

根据错误,看起来 Docker 解释CMD为 shell 形式或默认的附加参数ENTRYPOINT

\n

实际上仍然不确定为什么会发生,但CMD改为

\n
CMD uvicorn app.main:app --host 0.0.0.0 --port 8000\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
ENTRYPOINT ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]\n
Run Code Online (Sandbox Code Playgroud)\n

应该可以解决你的问题

\n

另外,最好使用uvicorn可执行文件的完整路径(/usr/bin/uvicorn或者默认安装的位置?)。CMD这只是我的观点,但这可能是解释为参数而不是命令的原因。

\n

PS 另外,这里是docker 文档的注释:

\n
\n

注意
\nexec 形式被解析为 JSON 数组,这意味着您必须在单词周围使用双引号 (\xe2\x80\x9c),而不是使用单引号 (\xe2\x80\x98)。

\n
\n

所以exec form语法必须满足JSON语法的条件。

\n