How to Deploy Flask Apps on Vultr using Nginx and Gunicorn

Deploy Flask Applications

Flask is a Python framework for building web applications. With Flask, developers can easily define routes, handle HTTP requests and responses, and render dynamic content using Jinja2 templates. It also supports extensions allowing developers to integrate features like database access, form handling, and user authentication.

Gunicorn stands for “Green Unicorn”, it is a Web Server Gateway Interface (WSGI) HTTP server for Python. Gunicorn is designed to be a fast and scalable HTTP for running Python web applications.

In this article, we are going to deploy a Flask application using Gunicorn, we are also going to set up a reverse proxy using Nginx and implement HTTPS by requesting a free SSL certificate from Let’s Encrypt.

Deploy Vultr Optimized Cloud Instance

  • Sign up and log in to the Vultr Customer Portal.
  • Navigate to the Products page.
  • From the side menu, select Compute.
  • Click the Deploy Server button in the center.
Image2
  • Choose Optimized Cloud Compute as the server type.
  • Choose a server Location.
  • Choose Ubuntu 22.04 as the operating system.
Image4
  • Choose a suitable plan.
Image1

  • Choose any Additional Features if required.
  • Click Deploy Now.
Image3

Set Up a Python Virtual Environment

In this section, we are going to create a python virtual environment that will be used set up the project directory.

1. Install the python3-venv, to create virtual environments.

$ sudo apt install python3-venv

2. Create a virtual environment.

$ python3 -m venv myenv

3. Activate the virtual environment. Test

$ source myenv/bin/activate

Add Your Demo Application Code Files

In this section, we are going to clone the GitHub repository in which our code files are present, install some required dependencies, and start a Gunicorn server.

1. In your virtual environment, clone the GitHub repository.

(myenv) $ git clone https://github.com/mayankdebnath/flask-todo-demo.git

2. In the app.py  file, we are using the ProxyFix middleware provided by Werkzeug to fix headers when the application is behind a reverse proxy server. The app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1) line configures the flask application to use the ProxyFix middleware.

3. This configuration is important for applications deployed in production environments where reverse proxy servers like Nginx are used.

Navigate to the project directory.

(myenv) $ cd flask-todo-demo/sample/

4. Install the flask package.

(myenv) $ pip install flask

5. Install the gunicorn package.

(myenv) $ pip install gunicorn

6. Navigate to the project directory.

(myenv) $ cd sample

7. Allow incoming connections to port 5000.

(myenv) $ ufw allow 5000

8. Test the app by starting a Gunicorn server.

(myenv) $ gunicorn -b 0.0.0.0:5000 app:app

9. Access the app on the URL http://server-ip:5000.

Create a System Service

In this section, we are going to create a systemd service for our application that starts automatically and starts a Gunicorn server when the system boots up.

1. Get the gunicorn path.

(myenv) $ which gunicorn

Copy this path to your clipboard for later use.

2. Create a system service.

(myenv) $ sudo nano /etc/systemd/system/app.service

3. Paste the following configurations into the file.

[Unit]

Description= Daemon for Sample Demo Application

After=network.target

[Service]

User=example_user

Group=example_user

WorkingDirectory=/example_user/sample

ExecStart=/example_user/sample/venv/bin/gunicorn -b 0.0.0.0:5000 app:app

Environment="SERVER_NAME=domain_name"

[Install]

WantedBy=multi-user.target

Replace User and Group values with the actual values, WorkingDirectory with the project directory path, Execstart with the actual Gunicorn path you copied earlier including the executable binary. Also, replace the domain_name with your actual domain name.
Save and exit the file.

4. Start the service.

$ sudo systemctl start app

5. Check the status of the service.

$ sudo systemctl status app

6. If the service is working then active otherwise, you may need to check the configurations of the service.

7. Enable the service to start automatically whenever the system boots up.

$ sudo systemctl enable app

Configuring Nginx as a Reverse Proxy

Nginx acts as a reverse proxy between your web server and clients. It directs incoming requests based on your request configuration settings. In this section, we are going to configure our application for reverse proxy for efficient request handling and load balancing. We are also going to request a free SSL certificate from Let’s Encrypt to implement HTTPS that secures the communication between a user and a web server for our domain.

1. Log in to the Vultr Customer Portal.

2. Navigate to the Products page.

3. From the side menu, expand the Network drop-down, and select DNS.

4. Click the Add Domain button in the center.

5. Follow the setup procedure to add your domain name by selecting the IP address of your server.

6. Set the following hostnames as your domain’s primary and secondary nameservers with your domain registrar.
ns1.vultr.com
ns2.vultr.com

7. Install Nginx.

$ sudo apt install nginx

8. Create a file named app.conf.

$ sudo nano /etc/nginx/sites-available/app.conf

9. Paste the following configuration into the file.

server {

        listen 80;

        listen [::]:80;

        server_name example.com www.example.com;

        location / {

            proxy_pass http://127.0.0.1:5000/;

            proxy_set_header Host $host;

            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_set_header X-Forwarded-Proto $scheme;

        }

    }

10. Make sure to replace example.com with your actual domain name.
Save and exit the file.

11. Activate the virtual host configuration.

$ sudo ln -s /etc/nginx/sites-available/app.conf /etc/nginx/sites-enabled/

12. Test the configuration to detect errors.

$ sudo nginx -t

13. Restart the nginx server.

$ sudo systemctl reload nginx

14. Allow incoming connections to port 80.

$ sudo ufw allow 80/tcp

15. Allow incoming connections to port 443.

$ sudo ufw allow 443/tcp

16. Install the certbot package.

$ sudo snap install --classic certbot

17. Request a new SSL certificate for your domain.

$ sudo certbot --nginx -d example.com -d www.example.com

Make sure to replace example.com with your actual domain. You can visit the app URL at https://server-ip. The page should look like this.

Image5

Conclusion

In this article, we explored how to deploy a Flask application using Nginx reverse proxy and Gunicorn. We also secured the application by adding an SSL certificate and enabling HTTPS access.

This is a sponsored article by Vultr. Vultr is the world’s largest privately-held cloud computing platform. A favorite with developers, Vultr has served over 1.5 million customers across 185 countries with flexible, scalable, global Cloud Compute, Cloud GPU, Bare Metal, and Cloud Storage solutions. Learn more about Vultr.