docker 码头集装箱坠毁:/箱/sh:1:[uvicorn,:未找到

ttp71kqs  于 2023-01-04  发布在  Docker
关注(0)|答案(3)|浏览(136)

我是Docker的新手,正试图将我的FastAPI应用程序Dockerize。首先,我创建了一个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

它显示Container在创建后几秒钟退出。
然后我运行这个命令:

docker logs fastapi_api_1

上面写着:

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

不知道是什么原因。尝试了一些我在网上找到的解决方案,但都没有成功。我的requirementsidertxt文件中确实有uvicorn。
帮助将是appriciated。请让我知道如果需要额外的信息。

bfnvny8b

bfnvny8b1#

注意:您不需要手动执行docker build -t fastapi .。Docker-compose将为您执行此操作(因为您设置了build: .)但是!您必须使用--build参数(docker-compose up --build)运行up命令到force rebuild image even if it exists
关于你的问题:
下面是关于RUNENTRYPOINTCMDvery good article(和one more
下面是CMD的三种形式:

  • CMD [“可执行文件”,“参数1”,“参数2”](exec格式,首选)
  • CMD [“param 1”,“param 2”](在exec表单中设置ENTRYPOINT的其他默认参数)
  • CMD命令param 1 param 2(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文档的注解:

exec表单被解析为JSON数组,这意味着您必须在单词两边使用双引号(“),而不是单引号(')。
因此exec form语法必须满足JSON语法的条件。

plicqrtu

plicqrtu2#

所以,基本上是有问题的docker。我已经创建了多个图像。我删除了所有的,并再次运行相同的命令,它的工作。我不知道确切的原因,但它现在的工作。
我认为发生的事情是,而不是删除旧的图像和创建一个新的。我只是做

docker-compose down

然后

docker-compose up -t

我认为那个指挥官没有考虑到这些变化。
然后我就跑:

docker-compose up --build

我认为这创造了一个新的形象,并且成功了。
然后我注意到至少创建了10个图像。我删除了所有的图像,并运行了相同的命令:

docker build .
docker-compose up -t

结果又恢复正常了。
因此,基本上不是使用创建新映像,而是使用未正确创建的旧映像:

docker-compose up --build

简而言之,无论何时更改docker文件或docker-compose.yml,都应该使用docker-compose up --build,而不是docker-compose up -t
这可能会令人困惑,但我也是非常新的 Docker 。
谢谢大家的帮助!

4jb9z9bj

4jb9z9bj3#

我的 docker-compose 环境中的 Dockerfile 也遇到过同样的问题,其中包含

COPY ./requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt
RUN pip install uvicorn==0.20.0
CMD ["uvicorn", "--host", "0.0.0.0", "--port", "6000", "app:app"]

因此,我不需要在我的docker-compose.yml中添加额外的command:
结果是,如果您在 * requirements.txt * 中安装 uvicorn,就像我出于测试目的所做的那样
然后在本地安装
跳过RUN pip install uvicorn==0.20.0,这意味着,
没有/usr/bin/uvicorn“可执行文件”可用,只是在 site-packages 中的某个地方,CMD将失败。
因此,如果您在 requirements.txtDockerfile 中使用 uvicorn,您也许可以
强制重新安装

RUN pip install --ignore-installed uvicorn==0.20.0

在停靠文件中,
或者设置PATH在python的内部找到它
或者--我发现的是保持图像尺寸小的更好的解决方案--是从 requirements.txt 中删除 uvicorn...

相关问题