How to Deploy a Flask Application with uWSGI, Nginx, and SSL on Debian 10

After building a Flask web application, you’ll quickly discover that its built-in server is intended primarily for development use. This walkthrough will demonstrate how to deploy your Flask project on a Debian 10 cloud server using Nginx as the reverse proxy, uWSGI as the application server, and Certbot for securing your site with SSL.

Prerequisites for Deploying Flask on Debian 10

  • A Debian 10 system with all packages up to date
  • Root access or sudo privileges
  • A domain name is optional but recommended

You can proceed with the setup without a domain by configuring Nginx with localhost. However, note that obtaining a valid SSL certificate via Certbot won’t be possible in that case, so the SSL setup portion should be omitted.

Step 1: Installing Nginx on Debian 10

Begin by installing the Nginx package on your server:

Once installed, test Nginx by entering your server’s IP address into a browser. If it’s functioning correctly, the default Nginx welcome page should be displayed.

Should you have a domain name, make sure to configure your DNS records to point to your server. The sample configuration for this guide includes:

  • IPv4 Address: 192.0.2.123
  • Server Names: example.com and www.example.com

 

Step 2: Installing Flask and Configuring uWSGI

Begin by installing the necessary Python development tools and the Flask and uWSGI packages:

  # apt install python3-pip python-dev
  # pip3 install uwsgi flask

Next, create a directory to store your website’s files:

If you already have a Flask project to deploy, copy it into the /var/www/example directory. Otherwise, you can create a simple test app as shown below:

  # nano /var/www/example/main.py

Insert the following content into the file:

  from flask import Flask
  app = Flask(__name__)

  @app.route("/")
  def index():
      return "Hello World!"

  if __name__ == "__main__":
      app.run(host="0.0.0.0")

Now, set up a configuration file for uWSGI:

  # nano /var/www/example/config-uwsgi.ini

Paste the following configuration into the file:

  [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

You can increase the number of processes for better performance on more powerful servers.

Step 3: Configuring Nginx for Flask and uWSGI

Start by deleting the default Nginx configuration file:

  # rm /etc/nginx/sites-enabled/default

Next, create a custom Nginx configuration file:

  # nano /var/www/example/config-nginx.conf

Add the following configuration to the file. If you’re not using a domain name, replace example.com and www.example.com with localhost under server_name:

  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 to make Nginx recognize this configuration by linking it to the conf.d directory:

  # ln -s /var/www/example/config-nginx.conf /etc/nginx/conf.d/

To apply the new settings, restart the Nginx service:

Step 4: Launching the uWSGI Application Server

Although Nginx is now set up to forward requests to uWSGI, the application server hasn’t been started yet. Use the nohup command to run uWSGI in the background:

  # nohup uwsgi /var/www/example/config-uwsgi.ini &

To test that the process continues after exiting the terminal, press Ctrl + C to send the SIGINT signal. You’ll observe that the uWSGI process stays active in the background.

For a production-grade deployment, it’s advisable to configure uWSGI to start automatically using systemd.

Finally, open your website in a browser. If everything is functioning properly, you should see the message: Hello World!

Step 4: Launching the uWSGI Application Server

Although Nginx is now set to forward traffic to uWSGI, the uWSGI service still needs to be started. Use nohup to run it in the background:

  # nohup uwsgi /var/www/example/config-uwsgi.ini &

After launching, press Ctrl + C to issue a SIGINT signal and confirm the process continues to run in the background. For long-term use in a production environment, it is best to configure uWSGI to start at boot using a systemd service.

Open your web browser and visit the server’s address. You should see the Hello World! message displayed from your Flask application.

Step 5: Securing Your Flask Application with SSL

If you’re using a public domain, you can add HTTPS support using a free SSL certificate from Let’s Encrypt via Certbot.

Begin by installing Certbot along with the Nginx plugin:

  # apt install certbot python-certbot-nginx

Next, issue a request for an SSL certificate:

Follow the interactive prompts. Accept the terms of service and confirm which domain names should receive SSL coverage by pressing Enter to choose all available options.

When asked, choose the option to automatically redirect all HTTP traffic to HTTPS for secure browsing.

Conclusion

With the help of this beginner-friendly guide, your Flask application is now live on a Debian 10 server, served via Nginx and uWSGI, and protected by an SSL certificate through Certbot. For full deployment readiness, ensure uWSGI runs at boot as a restricted user. Refer to the official Flask and uWSGI documentation for recommended production practices.

Source: vultr.com

Create a Free Account

Register now and get access to our Cloud Services.

Posts you might be interested in:

Moderne Hosting Services mit Cloud Server, Managed Server und skalierbarem Cloud Hosting für professionelle IT-Infrastrukturen

How to Install and Secure Apache OpenMeetings on CentOS 7

Apache, Tutorial

Linux file permissions with this comprehensive guide. Understand how to utilize chmod and chown commands to assign appropriate access rights, and gain insights into special permission bits like SUID, SGID, and the sticky bit to enhance your system’s security framework.