Score:0

Debug a Nginx vhost as a reverse proxy for a Uvicorn Python API

in flag

I have a (Python, DRF-based) API, running as a Uvicorn service on port 8002 on a Debian server. It runs with no apparent issue, since when I do curl http://127.0.0.1:8002/videos/, I get the expected API response (I also have tested it when deployed on Heroku, with no issue).

I need to serve it publicly with Nginx, so I configured a new Nginx vhost as a reverse proxy as followed:

 upstream my_api {
     server 127.0.0.1:8002;
 }
 
 server {
 
     server_name example.com;
 
     location / {
         # Pass to Uvicorn/Gunicorn web server service
         proxy_pass http://my_api;
         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;
     }

}

error_log /home/www/mydomain.log info;

On the browser, I get a 400 Bad Request error, whether it is on http://example.com/videos/ or even on http://example.com/ or http://example.com/whatever.

When I tail the /home/www/example.log Nginx vhost log file, I don't get any pertinent information, or logs from other vhosts, like the following:

2021/07/09 12:05:49 [info] 24698#24698: *233765 client 55.36.148.206 closed keepalive connection
2021/07/09 12:06:12 [info] 24698#24698: *233772 client 217.244.66.202 closed keepalive connection
2021/07/09 12:06:13 [info] 24698#24698: *233775 client closed connection while waiting for request, client: 63.210.40.102, server: 0.0.0.0:80

(Note: the unique endpoint works for /videos/ route but not for /videos route - this will be fixed later but anyway that shouldn't interfere with the question.)

Any idea how to debug/understand where this 400 error comes from?

Michael Hampton avatar
cz flag
Check your application logs.
in flag
Doesn't the /home/www/example.log as configured in the vhost, replace the application log?
Michael Hampton avatar
cz flag
You should hope not! How else would you be able to debug your application if you are not logging?
in flag
My question is precisely about logging. As stated, I have configured the vhost to log to /home/www/example.log, but nothing appears in the log about the 400. I'm not sure I understand your point
Michael Hampton avatar
cz flag
You seem to be confusing the nginx logs with your application's logs. These are separate and distinct.
in flag
Oh sorry I thought you were referring to another Nginx app log, not my API app served by Uvicorn. Gotcha. So actually I was assuming the error wasn't coming from the application, since I can curl it successfully, and since I was (wrongly) assuming 400s were generated by Nginx, but you are right, the error is on the app's side. Thanks
Score:0
in flag

Thanks to Michael Hampton's remarks, it appeared that the 400 errors were not on Nginx's side, but on the Python app's side served by Gunicorn/Uvicorn, even though the curl was working locally.

So it just needed to show the Gunicorn logs to debug it, by launching it manually with the debug logs on, this way:

gunicorn -k uvicorn.workers.UvicornWorker --bind "0.0.0.0:8002" --log-level debug my_api.asgi:application
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.