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
 
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
 
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
 
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.

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.