DEV Community

Cover image for Deploy Flask The Easy Way With Gunicorn and Nginx!

Deploy Flask The Easy Way With Gunicorn and Nginx!

brandon_wallace on January 29, 2021

Introduction After creating a Flask application you probably want people to see it. This tutorial will show you how to deploy your Flask...
Collapse
 
xiaogang profile image
xiaogang •

Thanks. Following these steps, I successfully deployed the Flask project using Gunicorp and learned to write services into Linux services

Collapse
 
brandonwallace profile image
brandon_wallace •

I am glad that you found my article useful.

Collapse
 
bjarmstr profile image
bjarmstr •

So close to getting this working but myproject produces a SSL_error. I had to make a few changes along the way. For instance, pipenv didn't install well without using sudo.
I thought the problem was where pipenv installed my virtual environment. It is not in /var/www/myproject/.venv but way down in /home/pi/.local somewhere but changing folder to this didn't solve the problem.

sudo systemctl status myproject.service produces the following error:
myproject.service:9: Missing '='.

Any ideas on where to go looking to fix this?

Collapse
 
brandonwallace profile image
brandon_wallace • • Edited

It looks like you have a syntax error in the myproject.service file. It appears that you are missing an equal sign somewhere. Check this file /etc/systemd/system/myproject.service for syntax errors.

Collapse
 
bjarmstr profile image
bjarmstr •

Yes! Application deployed. Thanks for the quick answer, it gave me reassurance that my problem had to be something simple. To start with I didn't realize that the unix statement was a continuation of the ExecStart line, not a new line. I fixed this early-on but didn't restart the service after I did the daemon-reload so my mistake remained!
After a successful launch, I rebooted the computer and Gunicorn didn't start. I added Environment="PATH=/var/www/myproject/.venv/bin" to myproject.service and that seems to have solved problem.
Thanks for writing this step-by-step article.

Thread Thread
 
brandonwallace profile image
brandon_wallace • • Edited

Unfortunately, this line in the myproject.service file was wrapped due to the formatting. I added a backslash to the line to resolve the issue. Now it will read as one long line.

ExecStart=/var/www/myproject/.venv/bin/gunicorn --workers 3 --bind unix:/var/www/myproject/myproject.sock wsgi:app
Enter fullscreen mode Exit fullscreen mode

Thanks for letting people know about the Environment="PATH=...." issue. I did not need that variable.

Collapse
 
byterbit profile image
Byter-Bit •

Without placing an "index.html" file in the folder I get a "2 directory index of "/var/www/html/myproject2/" is forbidden"
I've tried changing the user and group to www-data and, as a last resort, running "sudo chmod -R 777 myproject2" and then restarting nginx.

When I do place an "index.html" file there it runs, and not the python file.
I am attempting to run the program on an external Ubuntu server using the ip address followed by /myproject2, as in xxx.xxx.xx.xx/myproject2

At least this shows the redirection to the folder is working -
I must say this has been rather hard to debug - more moving parts than I'm used to with Apache running PHP or Node files -
Yours seems to be the best written tutorial I've found. I've spent days running several others and getting nowhere :>(

Collapse
 
brandonwallace profile image
brandon_wallace •

Byter-Bit,

There is no need to set the permissions to 777. If you would like to access the /myproject2 route you must create a route in Flask. Look at the @app.route(...) line in the code. The route you need would look something like this:

Example 1:

@app.route('/myproject2')
def custom_route():
    '''Myproject2 page route'''

    return '<h1>My Project 2</h1>'
Enter fullscreen mode Exit fullscreen mode

Then in your browser you would access this custom route like this http://<ip_address>/myproject2. If you set the server_name line in Nginx you would use http://<domain_name>/myproject2 to access that page.

Example 2:

@app.route('/')
def index():
    '''Index page route'''

    return '<h1>Application Deployed!</h1>'
Enter fullscreen mode Exit fullscreen mode

The index route is accessible like this http://<ip_address> or if you set up Nginx you would use this http://<domain_name>.

Collapse
 
jishwin13 profile image
jishwin13 •

Hey, I followed the exact same steps but I am getting this error after I host it with nginx
12:10:20 [crit] 142389#142389: *1 connect() to unix:/root/status_report_automation/status_report_automation.sock failed (13: Permission denied) while connecting to upstream, client: 103.99.218.187, server: _, request: "GET / HTTP/1.1", upstream: upstream: "unix:/root/status_report_automatio...", host: ":8080"
Nginx is listening to port 8080

Collapse
 
brandonwallace profile image
brandon_wallace • • Edited

It looks like you have put your project in the /root directory.

/root/status_report_automation/
Enter fullscreen mode Exit fullscreen mode

It is better to put it in /var/www/ like this:

$ sudo mkdir /var/www/status_report_automation/
Enter fullscreen mode Exit fullscreen mode

Then set the correct permissions on the directory and files.

$ sudo chown -R $USER:www-data /var/www/status_report_automation/
Enter fullscreen mode Exit fullscreen mode

Make sure your systemd service file looks something like this in the service section:

[Service]
User=YOUR_USER_NAME_GOES_HERE
Group=www-data
WorkingDirectory=/var/www/status_report_automation/
ExecStart=/var/www/status_report_automation/.venv/bin/gunicorn --workers 3 --bind unix:/var/www/status_report_automation/status_report_automation.sock wsgi:app
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ipapop profile image
ipapop •

Your tutorial allowed me, after many different tutorials and trials, to get this flask-gunicorn -nginx setup to finally work on MY DESKTOP -ubuntu 22.04 LTS- .
Thank you for it !!
The only place I tripped ,although you specifically warned against it, was in the path to gunicorn in the myproject.service. I used your troubleshooting advices.

Collapse
 
abdomgdy profile image
Abdul-Rahman Magdy •

Hi is there a way to get this to work without buying a domain ?
so just using the server IP address to access the app.

Collapse
 
brandonwallace profile image
brandon_wallace •

There is no need to buy a domain to get this to work. You can access the web application using the IP address of the server. Using a domain name to access the web application is much easier than using the IP address.

Collapse
 
garyk2015 profile image
garyk2015 •

Missing certs and SSL setup, your code shows myproject but the screenshot shows myproject...just saying...

Collapse
 
brandonwallace profile image
brandon_wallace •

Thanks. I fixed it. SSL set up is for another article.