serving flask app using gunicorn + nginx showing 404 [ec2]
amazon-web-services, gunicorn, nginx, python-3.x, ubuntu
Solution
Did you do `nginx -s reload && systemctl restart nginx`?
Another thing which you could try is to make the bindings on a http port instead of a socket:
--bind 127.0.0.1:6767 #in systemd config
and change nginx config as follows:
location / {
include proxy_params;
proxy_redirect off;
proxy_pass http://127.0.0.1:6767;
}
Also why do you have private_ip in nginx config?
server_name private_ip_address;
Change that to
server_name "_";
# OR
server_name PUBLIC_IP;
and remove all default configs from `/etc/nginx/site-enabled`
1) use of server_name private_ip_address;?
Nginx uses the server_name to check with the host header of the incoming request, and that isn't the private address. (You usually access using either a domain name or the public address in the URL bar)
2) I deleted /etc/nginx/site-enabled/default dir to make things to get to working.
If your server_name is not set correctly, nginx processes the request using the default file or the server block containing `default_server`. Thus I asked you to delete that file just in case there was an issue with your server name ^_^
Also, what difference would it make to the performance of the API if I am binding it to a port instead of the socket file as suggested by the blog post?
This would typically be premature optimization, any difference you get will purely be within a margin of error compared to the bottlenecks caused by flask/python and especially database connections. Though please take this with a grain of salt as I do not have any reliable source to quote this on.
Problem
I am trying to serve a simple API by following this digitalocean tutorial. For testing I was earlier serving the API through gunicorn by doing a ``` $ gunicorn --bind 0.0.0.0:5000 trumporate.wsgi:app ``` And curling the API endpoint works inside the ec2 box ``` $ curl -X GET http://0.0.0.0:5000/api/v1/trump/rant/ { "foo": "bar" } ``` Now I shifted this gunicorn process to run at startup by making a systemd service ``` # /etc/systemd/system/trumporate.service [Unit] Description=Gunicorn instance for trumporate After=network.target [Service] User=ubuntu Group=www-data WorkingDirectory=/var/opt/trumporate ExecStart=/usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunicorn-error.log trumporate.wsgi:app [Install] WantedBy=multi-user.target ``` I have created the files - `/var/log/trumporate/gunicorn-error.log` - `/var/log/trumporate/gunicorn-access.log` and changed the ownership and group to `ubuntu` After enabling the service and rebooting, I checked the status ``` $ sudo systemctl status trumporate.service ● trumporate.service - Gunicorn instance for trumporate Loaded: loaded (/etc/systemd/system/trumporate.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2017-05-03 06:30:26 UTC; 1h 2min ago Main PID: 1122 (gunicorn) Tasks: 4 Memory: 92.2M CPU: 1.390s CGroup: /system.slice/trumporate.service ├─1122 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic ├─1264 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic ├─1266 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic └─1267 /usr/bin/python3 /usr/local/bin/gunicorn --workers 3 --bind unix:trumporate.sock -m 007 --access-logfile /var/log/trumporate/gunicorn-access.log --error-logfile /var/log/trumporate/gunic May 03 06:30:26 ip-172-31-25-173 systemd[1]: Started Gunicorn instance for trumporate. ``` Following the DO tutorial, I tried configuring nginx to proxy incoming requests on port 80 ``` $ cat /etc/nginx/sites-available/trumporate server { listen 80; server_name private_ip_address; location / { include proxy_params; proxy_pass http://unix:/var/opt/trumporate/trumporate.sock; } } ``` And then did a `$ ln -s /etc/nginx/sites-available/trumporate /etc/nginx/sites-enabled` ``` $ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` Now if I try to do `GET` request to the API endpoint from outside the ec2 box ``` $ curl -X GET http://public_ip/api/v1/trump/rant <html> <head><title>404 Not Found</title></head> <body bgcolor="white"> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.10.0 (Ubuntu)</center> </body> </html> ``` Same case when I try to do it from inside the ec2 container too ``` $ curl -X GET http://localhost:80/api/v1/trump/rant/ <html> <head><title>404 Not Found</title></head> <body bgcolor="white"> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.10.0 (Ubuntu)</center> </body> </html> ``` log files ``` # /var/log/nginx/access.log dev_box_ip - - [03/May/2017:05:50:45 +0000] "GET /api/v1/trump/rant/ HTTP/1.1" 404 580 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36" 127.0.0.1 - - [03/May/2017:06:13:26 +0000] "GET /api/v1/trump/rant/ HTTP/1.1" 404 178 "-" "curl/7.47.0" dev_box_ip - - [03/May/2017:07:42:42 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36" /var/log/nginx$ cat error.log /var/log/nginx$ /var/log/trumporate$ cat gunicorn-access.log /var/log/trumporate$ $ cat gunicorn-error.log [2017-05-03 06:28:41 +0000] [1884] [INFO] Starting gunicorn 19.7.1 [2017-05-03 06:28:41 +0000] [1884] [INFO] Listening at: unix:trumporate.sock (1884) [2017-05-03 06:28:41 +0000] [1884] [INFO] Using worker: sync [2017-05-03 06:28:41 +0000] [1889] [INFO] Booting worker with pid: 1889 [2017-05-03 06:28:41 +0000] [1890] [INFO] Booting worker with pid: 1890 [2017-05-03 06:28:41 +0000] [1891] [INFO] Booting worker with pid: 1891 [2017-05-03 06:29:48 +0000] [1884] [INFO] Handling signal: term [2017-05-03 06:29:48 +0000] [1889] [INFO] Worker exiting (pid: 1889) [2017-05-03 06:29:48 +0000] [1890] [INFO] Worker exiting (pid: 1890) [2017-05-03 06:29:48 +0000] [1891] [INFO] Worker exiting (pid: 1891) [2017-05-03 06:29:49 +0000] [1884] [INFO] Shutting down: Master [2017-05-03 06:30:27 +0000] [1122] [INFO] Starting gunicorn 19.7.1 [2017-05-03 06:30:27 +0000] [1122] [INFO] Listening at: unix:trumporate.sock (1122) [2017-05-03 06:30:27 +0000] [1122] [INFO] Using worker: sync [2017-05-03 06:30:27 +0000] [1264] [INFO] Booting worker with pid: 1264 [2017-05-03 06:30:27 +0000] [1266] [INFO] Booting worker with pid: 1266 [2017-05-03 06:30:28 +0000] [1267] [INFO] Booting worker with pid: 1267 /var/log/trumporate$ ``` EDIT Relevant part of the flask app ``` @app.route('/api/v1/trump/rant/') def return_rant(): foo = # logic return jsonify(rant=foo) ```