我有一个简单的 FastAPI 项目,名为
toyrest
,它运行一个简单的 API。代码如下所示。
from fastapi import FastAPI
__version__ = "1.0.0"
app = FastAPI()
@app.get("/")
def root():
return "hello"
我已经围绕它构建了常用的 Python 包基础设施。我可以安装该软件包。如果我运行
uvicorn toyrest:app
,服务器将在端口 8000 上启动并且一切正常。
现在我正在尝试让它在 Docker 映像中运行。我有以下 Dockerfile。
# syntax=docker/dockerfile:1
FROM python:3
# Create a user.
RUN useradd --user-group --system --create-home --no-log-init user
USER user
ENV PATH=/home/user/.local/bin:$PATH
# Install the API.
WORKDIR /home/user
COPY --chown=user:user . ./toyrest
RUN python -m pip install --upgrade pip && \
pip install -r toyrest/requirements.txt
RUN pip install toyrest/ && \
rm -rf /home/user/toyrest
CMD ["uvicorn", "toyrest:app"]
我构建 Docker 映像并运行它,将端口 8000 转发到正在运行的容器。
docker run -p 8000:8000 toyrest:1.0.0
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
当我尝试连接到
http://127.0.0.1:8000/
时,我没有得到任何响应。
大概是我错误地进行了端口转发。我尝试了端口转发参数的各种排列(例如
-p 8000
、-p 127.0.0.1:8000:8000
),但无济于事。
这是一个基本的 Docker 命令,我看不出我是怎么弄错的,但不知怎的,我就是这样。我做错了什么?
尝试将此行添加到您的
CMD
中的 ̀dockerfile`:
CMD ["uvicorn", "toyrest:app","--host", "0.0.0.0"]
编辑
它起作用的原因是因为这使得 uvicorn 在 0.0.0.0 上而不是 127.0.0.1 上运行在容器内
0.0.0.0 被 docker 暴露出来,因为它是 docker 容器的私有网络接口。您无法从容器外部看到 127.0.0.1。