如何访问 NGINX 代理背后的 FastAPI SwaggerUI 文档?

问题描述 投票:0回答:2

希望你能帮助我,这是我遇到的问题:

我的前端和后端服务器都运行在同一个 AWS EC2 实例上。因此,我创建了一个像这样的 NGINX 配置:

server {
        server_name NAME;
        listen 80 default_server;
        location / {
                proxy_pass http://127.0.0.1:5000;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_http_version 1.1;
        }
        location /api/ {
                proxy_pass http://127.0.0.1:8000;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_http_version 1.1;
        }
}

因此,任何对 “http://public_ip/api/” 的请求都会路由到 FastAPI 后端服务器,而对另一个端点的所有其他请求都会路由到前端 SPA。

这在大多数情况下都很好用。但是,如果我尝试访问 FastAPI "/api/docs""/api/redoc" 路由,则会出现问题。例如,当我调用 "/api/docs" 端点时,有一个对 "http://public_ip/openapi.json" 地址的请求。这显然不是以 "/api" 开头的端点。所以 NGINX 阻止了它并提出了一个错误的请求。

https://fastapi.tiangolo.com/advanced/behind-a-proxy/#about-proxies-with-a-stripped-path-prefix

我找到了本指南,但似乎与我的问题完全无关。至少我是这样理解的。

任何帮助表示赞赏。提前致谢。

nginx swagger-ui fastapi
2个回答
4
投票

'openapi_url' 参数传递给 FastAPI() 似乎是一个很好的解决方案。通过 openapi_url= '/api/openapi.json' 并且它对文档和 redoc 都是固定的。感谢任何其他/更好的解决方案来处理可能发生的所有重定向。

api = FastAPI(title="API_NAME",
              description="API_DESC",
              version="0.2.0",
              docs_url='/api/docs',
              redoc_url='/api/redoc',
              openapi_url='/api/openapi.json')

0
投票

对我来说,它的工作方式如下:

我的docker容器的入口点脚本:

echo "Running the FastAPI server"
uvicorn server:app --host 0.0.0.0 --port 8000 --app-dir dashboard/api/ --root-path /api/ --forwarded-allow-ips "*" --reload &

FastAPI 应用程序:

import uvicorn 

from typing import Union
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware 

app = FastAPI() # root_path="/api/"

origins = ['*']

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
async def read_root():
    return {"message": "Hello from FastAPI"} 


@app.get("/test")
def read_main(request: Request):
    return {"message": "Hello World", "root_path": request.scope.get("root_path")}


# if __name__ == "__main__":
#     uvicorn.run(app, host='0.0.0.0', port=8000)

NGINX 配置:

upstream dashboard {
  server localhost:8081;
}

upstream apiserver {
  server localhost:8000;
}

server {
    listen 8080 default_server;
    listen [::]:8080 default_server;
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;
    server_name _;
    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ =404;
    }
    location /dashboard/ {
        proxy_pass http://dashboard;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    location /api/ {
        rewrite  ^/api/(.*)  /$1 break;
        proxy_set_header Host $http_host;
        proxy_pass http://apiserver;
    }
}

现在在 docker 容器之外一切正常:

curl http://0.0.0.0:28080/api/
curl http://0.0.0.0:28080/api/test
curl http://0.0.0.0:28080/api/openapi.json
curl http://0.0.0.0:28080/api/docs

在 docker 容器内它也可以工作:

curl http://0.0.0.0:8000/
curl http://0.0.0.0:8000/test
curl http://0.0.0.0:8000/openapi.json
curl http://0.0.0.0:8000/docs
© www.soinside.com 2019 - 2024. All rights reserved.