FastAPI挂载到域名的子路径下

发布时间 2023-10-31 20:46:15作者: waketzheng

概述

部署使用了Nginx+Supervisor+Gunicorn+Uvicorn
域名与后端服务可以在同一个服务器,也可以在不同的服务器
服务挂载在9000端口,域名的/api/mysite/用于对外提供后端接口服务

1. Python文件的Demo

# main.py
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse

app = FastAPI(root_path='/api/mysite')

@app.get('/app')
async def some_request_info(request: Request):
    return {'root_path': request.scope.get('root_path'),'url': request.url, 'headers': request.headers}

@app.get('/', include_in_schema=False)
async def home(request: Request):
    """首页自动跳转到 /docs"""
    return RedirectResponse(request.app.root_path + '/docs')

def docs_monkey_patch_for_root_path(app: FastAPI) -> None:
    # 用于解决app增加root_path后,本地docs不能访问的问题
    @app.get(app.root_path+'/{path:path}', include_in_schema=False)
    @app.post(app.root_path+'/{path:path}', include_in_schema=False)
    async def redirect_docs(path: str):
        return RedirectResponse('/' + path)

docs_monkey_patch_for_root_path(app)

2. supervisor配置

[program:mysite]
environment =
  SENTRY_ID=a5b4df500281a963532180a68616b7d6,
  START_SENTRY=1
command=poetry run gunicorn main:app --workers 2 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:9000
directory=/home/ubuntu/coding/mysite
stdout_logfile=/home/ubuntu/coding/mysite/supervisor.log
user=ubuntu

numprocs=1
autostart=true
startsecs=10
autorestart=true
startretried=3
redirect_stderr=true
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=20

3. nginx配置

upstream mysite_api {
   # 如果不是在同一个服务器,则把127.0.0.1改成对应的服务器IP
   server 127.0.0.1:9817;
}
server {
  ...
  location /api {
    rewrite ^/api/mysite/(.*) /$1 break;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://mysite_api;
  }
}