我的基于 FastAPI 的应用程序有问题。在本地,我的应用程序工作得很好,但是当尝试使用 docker 运行它时,我无法连接它。还在安装了 Ubuntu 的不同机器上进行了尝试,并且运行得很好。
还尝试在端口 8080 上使用 Flask 应用程序使用不同的容器,并且工作正常。
.
└── root_directory/
├── venv/
├── .gitignore
├── database.py
├── docker-compose.yaml
├── Dockerfile
├── main.py
├── models.py
├── README.md
└── requirements.txt
主.py文件
from fastapi import FastAPI
app = FastAPI()
@app.get("/hello")
def hello_world():
return "hello"
Dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.11
ENV PYTHONBUFFERED True
WORKDIR /app
COPY . .
WORKDIR /app
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
docker-compose.yaml
version: "3.8"
services:
api:
container_name: api
build:
context: .
command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload
volumes:
- ./:/app
ports:
- "8000:8000"
db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: example
POSTGRES_USER: host
POSTGRES_DB: movies_app
ports:
- '5432:5432'
容器返回的日志
api | INFO: Will watch for changes in these directories: ['/app']
api | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
api | INFO: Started reloader process [1] using WatchFiles
db-1 |
db-1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
db-1 |
db-1 | 2024-01-11 02:37:33.905 UTC [1] LOG: starting PostgreSQL 16.1 (Debian 16.1-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
db-1 | 2024-01-11 02:37:33.905 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db-1 | 2024-01-11 02:37:33.905 UTC [1] LOG: listening on IPv6 address "::", port 5432
db-1 | 2024-01-11 02:37:33.908 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db-1 | 2024-01-11 02:37:33.912 UTC [29] LOG: database system was shut down at 2024-01-11 02:37:25 UTC
db-1 | 2024-01-11 02:37:33.914 UTC [1] LOG: database system is ready to accept connections
api | INFO: Started server process [8]
api | INFO: Waiting for application startup.
api | INFO: Application startup complete.
如您所见,没有日志显示客户端尝试连接到 api 服务器
因此,如果有人遇到同样的问题,那么我找到了适合我的解决方案。
原始答案找到了这里
逐步解决:
进入 docker 正在使用的 WSL 实例的终端
在 shell 中输入
ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
以获取 WSL 实例的 IP
在终端中输入
netsh interface portproxy add v4tov4 listenport=8000 listenaddress=0.0.0.0 connectport=8000 connectaddress=x.x.x.x
,其中 connectaddress 是第二步中的 WSL ip,listenport 和 connectport 等于您要绑定的端口。
记得以管理员身份打开终端
有谁知道为什么这个问题只发生在 fastapi 容器中?
编辑:更有趣的是,我现在检查了如果我们为 uvicorn 服务器设置不同于 8000 的端口,它确实可以工作。