Deploy a Flask Website on Nginx with uWSGI
Once you've created a Flask app, you'll find that the included web server is best suited for development. In this guide, you'll learn how to host your Flask app on a Debian 10 cloud server instance with an Nginx web server, Certbot for SSL, and uWSGI application server.
Prerequisites
- A fully-updated Debian 10 server
- Root privileges to the server
- A registered domain name is optional, but recommended.
You can follow this tutorial without a domain name by using localhost in the Nginx configuration step. You won't be able to install a valid SSL certificate, so skip the Certbot instructions.
1. Install Nginx
Install the Nginx package.
# apt install nginx
Test Nginx by navigating to the server's IP address in a browser. Verify the Nginx web page appears.
If you have a registered domain, set up DNS entries for your server. This tutorial uses the following values:
- IPv4 address: 192.0.2.123
- Server names: example.com & www.example.com
2. Set up Flask and uWSGI
Install uWSGI and Flask.
# apt install python3-pip python-dev # pip3 install uwsgi flask
Create a website home directory.
# mkdir /var/www/example
If you have a Flask application to deploy, move it to the /var/www/example directory.
Or, you can create a simple Flask application for testing this guide.
# nano /var/www/example/main.py
Paste in:
from flask import Flask app = Flask(__name__) @app.route("/") def index(): return "Hello World!" if __name__ == "__main__": app.run(host="0.0.0.0")
Create config-uwsgi.ini for uWSGI.
# nano /var/www/example/config-uwsgi.ini
Paste in:
[uwsgi] app = main module = %(app) callable = app socket = /var/www/example/example.sock chdir = /var/www/example chmod-socket = 666 processes = 4 die-on-term = true
The processes line can be set higher for larger servers.
3. Set up Nginx
Remove the default Nginx configuration.
# rm /etc/nginx/sites-enabled/default
Create a new Nginx configuration file.
# nano /var/www/example/config-nginx.conf
Paste in the following content. If you do not have a registered domain name, use localhost for server_name in place of example.com and www.example.com.
server { listen 80; listen [::]:80; server_name example.com www.example.com; location / { include uwsgi_params; uwsgi_pass unix:/var/www/example/example.sock; } }
Create a symbolic link from your Nginx configuration to the
conf.d
directory.# ln -s /var/www/example/config-nginx.conf /etc/nginx/conf.d/
Restart Nginx.
# systemctl restart nginx
4. Run uWSGI
Nginx is configured to proxy traffic to uWSGI, but the service isn't running yet. Start uWSGI with nohup.
# nohup uwsgi /var/www/example/config-uwsgi.ini &
Press Ctrl + C to send the SIGINT signal and see that the process still runs in the background. For production use, we recommend running uWSGI at startup under systemd.
Navigate to your site in a web browser and verify you see the "Hello World!" message.
5. Install SSL Certificate
If you have a public domain name, configure the webserver for HTTPS with a free Let's Encrypt certificate using Certbot.
Install Certbot.
# apt install certbot python-certbot-nginx
Request an SSL certificate.
# certbot --nginx
Answer the questions when prompted by Certbot and agree to the terms of service.
Certbot will ask which domain names should have SSL support, press Enter to select all names.
When prompted, choose to redirect HTTP traffic to HTTPS.
Conclusion
After following this beginner tutorial, your Nginx web server runs Flask application on uWSGI, secured with Certbot. For full production use, you should also run uWSGI on startup as a normal user with limited permissions. See the uWSGI best practices and Flask documentation for more information.