skip to Main Content

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


  1. your ngnix config is wrong. you don’t use root directive for reverse proxying with nginx, but instead proxy_pass. the tutorial you’ve posted is right. the changes you should do:

    server {
        listen 80;
        server_name your_domain www.your_domain; # place here your website domain (optional directive)
    
        location / {
            proxy_pass http://unix:/root/baseweb/baseweb.sock;
        }
    }
    
    • listen tells were the nginx server should listen to requests. it could be only the port (80), ip:port (68.183.68.148:80), an unix socket (unix:/var/run/nginx.sock), etc…
    • the proxy_pass directive acts as a reverse proxy, forwarding traffic to the provided URL.
    • root is for serving static files.

    read more at:

    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)

    Login or Signup to reply.
  2. 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:

    server {
        listen 80;
        server_name baserank.net www.baserank.net;
    
        location / {
            proxy_pass http://127.0.0.1:5000;
        }
    }
    

    Next if you see your Flask Installation, please check which user nginx is using by using:

    cat /etc/nginx/nginx.conf | grep user
    # user www-data;
    

    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:

    /root/baseweb/venv/bin/gunicorn --workers 1 --bind unix:/var/run/baseweb.sock app:app
    

    And the corresponding nginx location conf:

    location / {
       proxy_pass http://unix:/var/run/baseweb.sock;
    }
    

    If the nginx user can access the socket but you still get a 500 you should debug the socket using curl:

    curl --unix-socket /var/run/baseweb.sock http://localhost/
    

    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)

    Login or Signup to reply.
  3. 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 one project.socket, project.service is connected with project.socket.

    First, create project.socket. under the directory /etc/systemd/system/.

    [Unit]
    Description=My Flask App
    [Socket]
    ListenStream=/run/project.sock
    [Install]
    WantedBy=socket.target
    

    Second, create project.service. under the directory /etc/systemd/system/.

    [Unit]
    Description=My Flask App
    Requires=project.socket
    After=network.target
    
    [Service]
    User=username
    Group=www-data
    
    WorkingDirectory=/home/username/flaskapp
    ExecStart=/home/username/flaskapp/venv/bin/gunicorn --bind 0.0.0.0:5000 flaskapp:flaskapp
    
    Restart=always
    RestartSec=3
    
    [Install]
    WantedBy=multi-user.target
    

    After the configuration is done, reload the daemon by using systemctl daemon-reload and finally restart the service by systemctl restart project.

    Additionally, you can reconfigure Nginx reverse proxy if needed, like proxy_pass http://unix:/run/project.sock;

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search