I have a flask app that I would like to serve via a DO Droplet.
I have followed How To Serve Flask Applications with Gunicorn and Nginx on Ubuntu 22.04
This is my folder structure
root/
└── baseweb/
├── venv
├── app.py
└── app/
├── routes.py
└── templates/
└── index.html
app.py looks like this
from app import app
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
I have created a baseweb service
Description=Gunicorn instance to serve myproject
Requires=project.sock
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/root/baseweb
Environment="PATH=/root/baseweb/venv/bin"
ExecStart=/root/baseweb/venv/bin/gunicorn --preload --timeout 120 --bind unix:/baseweb/baseweb.sock -m 007 --work
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
and my nginx configuration (/etc/nginx/sites-available/baseweb
) – edited per arthur simas comment below
server {
list 80;
server_name baserank.net, www.baserank.net;
location / {
proxy_pass http://127.0.0.1:5000;
}
}
When i simply run app.py using my venv, i can access my flask app directly via the IP
if I run gunicorn --bind 0.0.0.0:5000 app:app
i can also access my app via the same IP.
But when i try to access via nginx (via the domain or the IP directly without running the app in console), i get timed out
I have spent hours trying to adjust settings, but i have no idea where this is going wrong – so any help is very much appreciated.
Edit 2023-02-17: Ngnix access.log
185.16.141.5 - - [17/Feb/2023:14:14:17 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
185.16.141.5 - - [17/Feb/2023:14:14:17 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
185.16.141.5 - - [17/Feb/2023:14:14:20 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
185.16.141.5 - - [17/Feb/2023:14:14:20 +0000] "GET / HTTP/1.1" 502 568 "http://baserank.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"
143.110.222.166 - - [17/Feb/2023:14:22:21 +0000] "GET / HTTP/1.1" 502 166 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 16_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1"
3
Answers
your ngnix config is wrong. you don’t use
root
directive for reverse proxying with nginx, but insteadproxy_pass
. the tutorial you’ve posted is right. the changes you should do:listen
tells were the nginx server should listen to requests. it could be only theport
(80
),ip:port
(68.183.68.148:80
), an unix socket (unix:/var/run/nginx.sock
), etc…proxy_pass
directive acts as a reverse proxy, forwarding traffic to the provided URL.root
is for serving static files.read more at:
ngx_http_core_module
–listen
ngx_http_proxy_module
–proxy_pass
also, be sure to create the service in systemd, at the correct path location and check if its running
sudo systemctl status myproject
(or nginx would not be able to forward traffic to it)There could be multiple issues that lead to a 502.
I would first make sure that your nginx configuration is being used at all when accessing baserank.net by proxy_pass’ing to 127.0.0.1:5000:
Next if you see your Flask Installation, please check which user nginx is using by using:
If you see something other than
root
here, it’s most likely that nginx is unable to access the socket as it’s inside the/root
directory.A better place to store the socket is
/var/run
but you’re good as long as the user nginx is running as can access the socket:And the corresponding nginx location conf:
If the nginx user can access the socket but you still get a 500 you should debug the socket using curl:
I would suspect the socket being under /root/ is the main culprit here.
You can quickly debug this by setting nginx users to root as well (but switch it back after that quick test and fix permissions accordingly)
According to your project service configuration, it seems that the project sock or socket file is missing in the service configuration. Generally located at
/etc/systemd/system/
.Generally, in a service file, there are two variants of file that are required in order to run your flask app’s first one is
project.service
, and the second oneproject.socket
,project.service
is connected withproject.socket
.First, create
project.socket
. under the directory/etc/systemd/system/
.Second, create
project.service
. under the directory/etc/systemd/system/
.After the configuration is done, reload the daemon by using
systemctl daemon-reload
and finally restart the service bysystemctl restart project
.Additionally, you can reconfigure Nginx reverse proxy if needed, like
proxy_pass http://unix:/run/project.sock
;