【问题标题】:Docker containers crashed: /bin/sh: 1: [uvicorn,: not foundDocker 容器崩溃:/bin/sh: 1: [uvicorn,: not found
【发布时间】:2021-12-08 22:24:07
【问题描述】:

我是 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"]

然后运行以下命令:

docker build -t fastapi .

命令运行成功。

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

version: "3"
services: 
  api:
    build: .
    ports:
      - 8000:8000
    env_file:
         ./.env

然后运行以下命令:

docker-compose up -d

运行成功:

    Network fastapi_default  Created                              0.7s 
 - Container fastapi_api_1  Started 

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

docker ps -a

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

然后我运行了这个命令:

docker logs fastapi_api_1

它说:

/bin/sh: 1: [uvicorn,: not found

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

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

【问题讨论】:

  • 该错误几乎总是意味着CMD 中的 JSON 数组语法有问题。您在问题中显示的内容似乎是正确的;仔细检查您在各个单词周围是否有直双引号,以及它们之间的普通空格(不是单引号、Unicode“弯”引号或不同的 Unicode 空格)。
  • 执行一次docker run myimage uvicorn 以查看其是否可用。只是为了排除它不是 CMD 语法的问题。 CMD 对我来说看起来不错。

标签: python docker fastapi


【解决方案1】:

注意:您不需要手动执行docker build -t fastapi .。 Docker-compose 会为你做这件事(因为你设置了build: .)但是!您必须运行带有--build 参数(docker-compose up --build)到force rebuild image even if it existsup 命令。

关于你的问题:

这是关于RUNENTRYPOINTCMDvery good article(和one more

这是CMD的三种形式:

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

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

其实还是不知道为什么会这样,但是把CMD改成

CMD uvicorn app.main:app --host 0.0.0.0 --port 8000

ENTRYPOINT ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

应该能解决你的问题

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

PS 另外这里是docker docs的注释:

注意
exec 形式被解析为 JSON 数组,这意味着您必须在单词周围使用双引号 (") 而不是单引号 (')。

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

【讨论】:

  • 是的,根据这个错误肯定需要使用uvicorn的完整路径
  • @AlexW 其实我不明白为什么uvicorn 解释为[uvicorn, 而不是uvicorn,即使它只是原始ENTRYPOINT 的一个参数...
  • 尝试了上述所有方法,但都没有成功。
  • 奇怪的是,即使将 CMD 从:CMD [ "uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000" ] 更改为 CMD uvicorn app.main:app --host 0.0.0.0 --port 8000,它仍然显示相同的错误:/bin/sh: 1: [uvicorn,: not found,即使没有方括号或逗号。
  • Entrypoint 可能并不好。
【解决方案2】:

所以,码头工人基本上有问题。我创建了多个图像。我删除了所有这些并再次运行相同的命令并且它起作用了。我不知道确切的原因,但它现在可以工作了。

我认为正在发生的是,不是删除旧图像并创建新图像。我只是在做

docker-compose down

然后

docker-compose up -t

我认为该命令没有考虑这些更改。

然后我跑了:

docker-compose up --build

我认为这创建了一个新图像并且它有效。

然后我注意到创建了至少 10 个图像。我删除了所有这些并运行了相同的命令:

docker build .
docker-compose up -t

它再次运行良好。

所以基本上不是使用创建新图像,而是使用未正确创建的旧图像:

docker-compose up --build

简而言之,当您在 dockerfile 或 docker-compose.yml 中进行更改时,您应该使用 docker-compose up --build 而不是 docker-compose up -t

这可能会令人困惑,但我对 Docker 也很陌生。

感谢大家的帮助!

【讨论】:

  • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
  • docker-compose downdon't delete默认图片(需要设置--rmi)和docker-compose up不要rebuild image if it already exists。所以你重用了相同的图像。对不起,我说You don't need to do docker build -t fastapi . manually时没有提到它
  • 没问题。我想这就是我们学习的方式。我被困在另一个步骤上。看看你是否可以帮助大声笑。 stackoverflow.com/questions/70298161/…
猜你喜欢
  • 2021-10-20
  • 2019-09-11
  • 2015-12-18
  • 2020-07-28
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 2018-06-06
  • 1970-01-01
相关资源
最近更新 更多