You are currently viewing How to Deploy Flask Applications on Ubuntu Using Nginx
How to Deploy Flask Applications on Ubuntu Using Nginx

How to Deploy Flask Applications on Ubuntu Using Nginx

Deploying a Flask application on Nginx typically involves setting up a WSGI server (like Gunicorn or uWSGI) to interface between the Flask application and Nginx, which acts as a reverse proxy. Below is a step-by-step procedure on how to deploy Flask Applications on Ubuntu Using Nginx.

Install Required Software

Install the necessary software. See a list of required software:

  • Python
  • pip (Python package manager)
  • Gunicorn (WSGI server)
  • Nginx (webserver)
  • virtualenv
sudo apt update
sudo apt install python3 python3-pip python3.12-venv nginx

We will use the following settings to illustrate this deployment. Note that this will affect the configurations in later steps. When following along, ensure that you adjust the paths as needed.

Work directory: /home/ubuntu/flaskapp

Virtual environment: /home/ubuntu/flaskapp/venv

Upload website files

There are several ways to get your website files to the server for deployment. The common method is by cloning a github repository, rsync, and scp.

# Commands to Get Files to the Server

### Using `rsync`
rsync -avz /path/to/local/directory/ ubuntu@your-server-ip:/home/ubuntu/flaskapp
# Sync files from a local directory to the server

scp -r /path/to/local/directory/ ubuntu@your-server-ip:/home/ubuntu/flaskapp
# Copy files from a local directory to the server

cd /home/ubuntu/flaskapp
git clone https://github.com/danielnjama/flaskapp.git 
# Clone the repository directly to the server

Ensure that once the files are uploaded onto the server, they sit in the root directory as defined in an earlier step.

Create a Virtual Environment and Install Dependencies

Navigate to the root folder, create a virtual environment, activate it, and install the dependencies.

cd /home/ubuntu/flaskapp
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install gunicorn    #install gunicorn incase it was not included in the requirements.txt

Test the Flask Application Locally(within the server)

At this stage, we can do a test to confirm if our app is running as expected. Run the following command:

gunicorn --bind 0.0.0.0:5000 app:app

Verify it’s working by visiting http://<your-server-ip>:5000

In case of errors, identify them from the terminal logs. Common errors are missing dependencies. Resolve all errors as needed and proceed to the next steps.

Configure Gunicorn as a Systemd Service

Create a systemd service file for Gunicorn at:

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

copy and paste the code below. Ensure to adjust the working directory as needed.

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

[Service]
User=www-data
Group=www-data
WorkingDirectory=/home/ubuntu/flaskapp
Environment="PATH=/home/ubuntu/flaskapp/venv/bin"
ExecStart=/home/ubuntu/flaskapp/venv/bin/gunicorn --workers 3 --bind unix:/home/ubuntu/flaskapp/flaskapp.sock app:app

[Install]
WantedBy=multi-user.target

Reload systemd and Start Gunicorn

sudo systemctl daemon-reload
sudo systemctl start flaskapp
sudo systemctl enable flaskapp

Configure Nginx as a Reverse Proxy

Create an Nginx server block at:

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

Copy and paste the code below, and adjust as needed. With the following block, you can configure to access your website from the domain name, and or the IP.

server {
    listen 80;
    server_name yourdomain.com and or publicIP;

    location / {
        proxy_pass http://unix:/home/ubuntu/flaskapp/flaskapp.sock;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /static/ {
        alias /home/ubuntu/flaskapp/static/;
    }

    error_log /var/log/nginx/flaskapp_error.log;
    access_log /var/log/nginx/flaskapp_access.log;
}

You may want to access the website only from the domain and not from the IP. By default, if the IP is left out in the block above, visiting the IP will display the nginx default page. We may want to take control of this and redirect the traffic from the IP to the domain name. Use the block below instead.

Redirect IP traffic to the domain name

#Update the code to match the following
sudo nano /etc/nginx/sites-available/flaskapp
# Redirect traffic from the server's public IP to the domain
server {
    listen 80;
    server_name your-server-ip;

    return 301 http://yourdomain.com$request_uri;
}

# Main server block for your domain
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;

    location / {
        proxy_pass http://unix:/home/ubuntu/flaskapp/flaskapp.sock;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /static/ {
        alias /home/ubuntu/flaskapp/static/;
    }

    error_log /var/log/nginx/flaskapp_error.log;
    access_log /var/log/nginx/flaskapp_access.log;
}

Enable the Site and Restart Nginx

Create a symbolic link to your Nginx configuration in the sites-enabled directory and restart Nginx:

sudo ln -s /etc/nginx/sites-available/flaskapp /etc/nginx/sites-enabled
sudo nginx -t
sudo systemctl restart nginx

Change Ownership or Permissions

Update the permissions as below to ensure that nginx and other processes have the necessary permissions to interact. Note that we use the user www-data. This user is a low-privilege account specifically intended for running web services, minimizing the risk of exploits gaining high-level permissions.

# Set ownership of the directory and socket file to www-data
sudo chown -R www-data:www-data /home/ubuntu/flaskapp

# Allow read, write, and execute for the directory
sudo chmod 755 /home/ubuntu/flaskapp

# Allow read and write for the socket file
sudo chmod 664 /home/ubuntu/flaskapp/flaskapp.sock

#add the Nginx user (www-data) to a group that owns the directory or socket file:
sudo usermod -aG ubuntu www-data

Once permissions are updated, restart the following services.

sudo systemctl daemon-reload
sudo systemctl restart flaskapp
sudo systemctl restart nginx

At this stage, your website should be accessible. In case of errors/website unreachable, inspect the logs. See below the logs’ location.

Application Monitoring and Maintainance

To support the application, we need to understand the location of error logs. This helps us troubleshoot the

application in times of failure and resolve errors.

#Check Gunicorn logs: 
journalctl -u flaskapp
journalctl -f -u flaskapp

Check for Nginx logs:

Access logs: /var/log/nginx/flaskapp_access.log
Error logs: /var/log/nginx/flaskapp_error.log
example:
tail -f /var/log/nginx/myflaskapp_error.log

Secure with HTTPS (Install free SSL certificate)

Use Certbot to secure your application with Let’s Encrypt SSL: Run the following commands and follow the prompts:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com www.yourdomain.com

MySQL Database Configuration

This guide assumes that you have already configured MySQL from your local development. In the live server, you need to set up a MySQL server in the same server as your code or use any other external MySQL service of your choice. In this guide, I will show you how to do a basic MySQL server setup. See the reference guide How to Install MySQL Database on Linux

Installing MySQL server

sudo apt update
sudo apt install mysql-server
sudo systemctl start mysql  #Start mysql service
sudo systemctl enable mysql #enable the service to start on reboot

Access Mysql database

There are a number of ways to achieve this, having followed the above setup. see below the options.

Option 1:
#Run the following command to access mysql database. Once prompted, enter your sudo password:
sudo mysql --defaults-file=/etc/mysql/debian.cnf

Option 2:
sudo cat /etc/mysql/debian.cnf
#This file has some default username and password. Use that to access the database, see example.
mysql -u debian-sys-maint -p #use the password provided.

Option 3:
#Run the mysql as sudo, this doesnt ask for password
sudo mysql -u root

Option 4:
#Run the following:
sudo -i
mysql

Option 5:
sudo mysql

Once you gain access, proceed to create a database and a database user. This information is then to be updated on your code.

#Create a database and switch to it
CREATE DATABASE mydatabase;
USE mydatabase;

#Create a User and Set a Password:
CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword'; 

#Grant Privileges to the User on the Database:
GRANT ALL PRIVILEGES ON mydatabase.* TO 'myuser'@'localhost';

#Flush Privileges:
FLUSH PRIVILEGES;

Update the database credentials for your code as needed. Once updated, reload and retry. If needed, proceed and create your database tables or do migrations.

Make a donation to support us


Web Hosting and email hosting Packages


For web development services, SEO services, Digital marketing strategies, website set up services, web hosting and domain registration; contact Dynamic Technologies.


Related Content: