tiangolo / uvicorn-gunicorn-fastapi-docker

Docker image with Uvicorn managed by Gunicorn for high-performance FastAPI web applications in Python with performance auto-tuning.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

set root-path to uvicorn

0anton opened this issue · comments

I'm trying to set root_path to uvicorn as suggested [1] using this image, but don't see any options to pass arguments:

uvicorn main:app --root-path /api/v1

How can I do it?

Refs:

  1. https://fastapi.tiangolo.com/advanced/behind-a-proxy/#providing-the-root_path

I struggled with this as well. Got it working in the end, albeit by setting root_path via the FastAPI object, e.g., app = FastAPI(root_path='/api/v1') and upgrading FastAPI.

Before upgrading it didn't work either using the current tiangolo/uvicorn-gunicorn-fastapi-docker:python3.8 image because it still has fastapi==0.55.1 installed. Try docker container run tiangolo/uvicorn-gunicorn-fastapi:python3.8 pip freeze | grep fastapi to verify. This image was last updated 3 months ago, probably just before the release of fastapi==0.56.0 (see PR).

Extending from tiangolo/uvicorn-gunicorn-fastapi-docker:python3.8 and then pip install --upgrade fastapi==0.61.1 did the trick for me.

@tiangolo will the images be updated in the near future?

@poppash
On my side it does not work I am getting an error in OpenApi
image

Python 3.7.8
fastapi 0.63.0

Run configuration:
uvicorn.run("app:app", host="0.0.0.0", port=port, reload=True)

I think the error is in the path here is console log:
127.0.0.1:54913 - "GET /api/v1/api/v1/openapi.json HTTP/1.1" 404 Not Found
Here is double path: /api/v1/api/v1/

commented

Gunicorn 20.1.0
fastapi 0.66.0

You can fix it with:
app = FastAPI(root_path=os.environ.get('ROOT_PATH'))

In this case you can change the ROOT_PATH with environment variable.

After that you can strip the ROOT_PATH within the proxy.

Example:
ROOT_PATH = /auth/v1

Remove the /auth/v1 from the endpoints.
@app.get("/create_token", tags=["User"]) -> Do no start it with /auth/v1 because it is added automatically

On the proxy you can strip it with:

apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: strip-auth-v1-from-path
spec:
  stripPrefix:
    prefixes:
      - /auth/v1

After that it must work properly.

I also struggled for hours by the way. Tried the class ConfigurableWorker(UvicornWorker) method and struggled hours with the Gunicorn config but nothing worked. The solution above worked perfectly.

For anybody coming here from the new ngrix-proxy version where the VIRTUAL_PATH option was introduced, this solution is very easy to set up. Just use app = FastAPI(root_path=os.environ.get('VIRTUAL_PATH')) and that will set your root correctly.

@0anton I came across this ticket while researching how to do this in gunicorn and passing --root-path=/api as so works for uvicorn

here's an excerpt from our docker-compose file:

command: ["uvicorn", "${PROJ_NAME}.api:app", "--host=0.0.0.0", "--port=80", "--root-path=/api", "--reload"]

I am in the process of documenting this property if it's of interest to anybody.

@devraj Thank you so much!
This really helped me, as I didn't want to scaffold root_path in the application itself, since I was using nginx as a reverse proxy in production with docker-compose.
Thanks a ton!

For people using nginx as a reverse proxy, and stuck on how to forward the traffic to the right container, this is my current configuration:

server {
    listen 80;
    server_name example.com;
    location / {
        # For my react frontend served by an nginx container
        proxy_pass http://localhost:7000;

    }
    location /api/{
       # For FastAPI app running in docker container, where the endpoint should be /api/
       # notice the trailing slash at the end, it is important,so that it performs stripping properly. 
    	proxy_pass http://localhost:8100/;
  }
}

@tiangolo, if it is required, I could add a section for nginx here in the documentation.