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
Related Content: