Deploying a Flask Application on a VPS Using Gunicorn and Nginx

5 min read
python bash

Deploying a Flask Application on a VPS Using Gunicorn and Nginx

This tutorial will guide you through the process of deploying a Flask application on a VPS using Gunicorn as the WSGI server and Nginx as the reverse proxy. We will use pipreqs to manage Python dependencies and set up HTTPS using Let's Encrypt.

Prerequisites

  • A Flask application ready to be deployed.

  • Access to a VPS (e.g., Ubuntu 20.04).

  • A registered domain name.

  • Basic knowledge of Linux command line operations.

Step 1: Set Up the VPS

Update and Upgrade the System

sudo apt update
sudo apt upgrade -y

Install Required Packages

Install essential packages for building Python packages and SSL:

sudo apt install -y python3-pip python3-venv nginx curl

Step 2: Clone the Flask Application

Clone Your Git Repository

Clone your Flask application from your version control system to your server:

git clone https://github.com/username/your-flask-app.git
cd your-flask-app

Replace https://github.com/username/your-flask-app.git with the URL of your repository.

Step 3: Set Up the Python Environment

Create and Activate a Virtual Environment

Create a virtual environment for your Flask application:

python3 -m venv venv
source venv/bin/activate

Install Dependencies Using pipreqs

First, install pipreqs:

pip install pipreqs

Generate a requirements.txt file based on your project imports:

pipreqs . --force

Then, install the dependencies from the requirements.txt file:

pip install -r requirements.txt

Step 4: Set Up Gunicorn

Install Gunicorn

Install Gunicorn in your virtual environment:

pip install gunicorn

Test Gunicorn Locally

Run Gunicorn to test it locally with your Flask app:

gunicorn --bind 0.0.0.0:8000 app:app

Replace app:app with your actual Flask application entry point (module_name:application_name).

Create a Systemd Service for Gunicorn

Create a service file for Gunicorn:

sudo nano /etc/systemd/system/developerbreeze.service

Add the following configuration to the file:

[Unit]
Description=Gunicorn instance to serve Flask application
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/your-flask-app
Environment="PATH=/path/to/your-flask-app/venv/bin"
ExecStart=/path/to/your-flask-app/venv/bin/gunicorn --workers 3 --bind unix:/path/to/your-flask-app/developerbreeze.sock app:app

[Install]
WantedBy=multi-user.target

  • Replace /path/to/your-flask-app with the actual path to your Flask app.

  • Replace app:app with your Flask application's entry point.

Start and Enable the Gunicorn Service

Enable and start the Gunicorn service:

sudo systemctl enable developerbreeze.service
sudo systemctl start developerbreeze.service

Check the status to ensure it's running:

sudo systemctl status developerbreeze.service

Step 5: Configure Nginx

Create an Nginx Configuration File

Create a new Nginx configuration file for your site:

sudo nano /etc/nginx/sites-available/developerbreeze

Add the following configuration:

# HTTP to HTTPS redirection
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name developerbreeze.com www.developerbreeze.com;

    # Redirect all HTTP requests to HTTPS
    return 301 https://developerbreeze.com$request_uri;
}

# Main server block for HTTPS
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name developerbreeze.com www.developerbreeze.com;

    ssl_certificate /etc/letsencrypt/live/developerbreeze.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/developerbreeze.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    root /path/to/your-flask-app;
    index index.html;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location / {
        include proxy_params;
        proxy_pass http://unix:/path/to/your-flask-app/developerbreeze.sock;
    }

    location /static {
        alias /path/to/your-flask-app/static;
    }

    location /favicon.ico {
        alias /path/to/your-flask-app/static/favicon.ico;
    }

    # Let's Encrypt verification for renewing SSL certificates
    location ~ /.well-known {
        allow all;
    }
}

  • Replace /path/to/your-flask-app with the actual path to your Flask app.

  • Ensure the SSL certificate paths are correct as managed by Certbot.

Enable the Nginx Site

Create a symbolic link in sites-enabled:

sudo ln -s /etc/nginx/sites-available/developerbreeze /etc/nginx/sites-enabled/

Remove the default Nginx configuration if necessary:

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

Test and Restart Nginx

Test the Nginx configuration for syntax errors:

sudo nginx -t

If there are no errors, restart Nginx:

sudo systemctl restart nginx

Step 6: Set Up SSL with Let's Encrypt

Install Certbot

Install Certbot for Nginx:

sudo apt install certbot python3-certbot-nginx

Obtain an SSL Certificate

Run Certbot to obtain and install the SSL certificate:

sudo certbot --nginx -d developerbreeze.com -d www.developerbreeze.com

Follow the prompts to complete the installation.

Verify SSL Renewal

Ensure the Certbot renewal process is set up correctly:

sudo certbot renew --dry-run

Step 7: Verify the Deployment

  • Access your site at https://developerbreeze.com to verify that it loads correctly over HTTPS.

  • Check Logs: Monitor Nginx and Gunicorn logs for any errors:

sudo tail -f /var/log/nginx/access.log
  sudo tail -f /var/log/nginx/error.log
  sudo journalctl -u developerbreeze.service -f
  

Conclusion

By following these steps, you have successfully deployed your Flask application using Gunicorn and Nginx, secured with SSL from Let's Encrypt. This setup provides a robust and scalable environment for running your web application.

Discussion (0)

Please sign in to join the discussion.

No comments yet. Be the first to share your thoughts!