Python API service
Configuring a Systemd Service for a Flask Python Application in Production
Deploying a Flask application in a production environment necessitates a rigorous configuration to ensure both reliability and security. This guide elucidates the process of configuring a Flask application as a systemd service on a Linux server, utilizing Gunicorn as the production WSGI server, and establishing the necessary network configurations for external access.
Step 1: Environment Preparation and Installation
Begin by ensuring that your Flask application is properly deployed and that a virtual environment is established.
- Create a Virtual Environment:
python3 -m venv /path/to/your/venv
- Activate the Virtual Environment:
source /path/to/your/venv/bin/activate
- Install Flask and Gunicorn:
pip install flask gunicorn
Step 2: Create and Configure the Systemd Service File
To deploy the Flask application as a service, a systemd service file must be created and appropriately configured:
- Create the Service File:
sudo nano /etc/systemd/system/flask_app.service
- Define the Service Configuration:
[Unit] Description=Flask Application After=network.target [Service] User=myuser WorkingDirectory=/path/to/your/flask_app ExecStart=/home/sergio/venv/bin/gunicorn -b 0.0.0.0:5000 api:app Restart=always Environment="PATH=/home/sergio/venv/bin" [Install] WantedBy=multi-user.target
- Replace
/home/sergio/venv
with the appropriate path to your virtual environment. - Replace
/path/to/your/flask_app
with the correct path to your Flask application directory. - Replace
api:app
with the appropriate filename (api.py
) and the Flask instance (app
). - Replace
myuser
with the intended user account that should execute the service.
- Replace
Step 3: Reload Systemd and Initiate the Service
- Reload the systemd daemon to incorporate the new service file:
sudo systemctl daemon-reload
- Enable the Service to start automatically upon system boot:
sudo systemctl enable flask_app.service
- Start the Flask Service:
sudo systemctl start flask_app.service
- Verify Service Status to ensure proper operation:
sudo systemctl status flask_app.service
Step 4: Configure Network Access
By default, Flask operates on port 5000
. It is imperative to ensure that this port is open for external access.
Using UFW (Uncomplicated Firewall)
If ufw
is used, execute the following command to open port 5000
:
sudo ufw allow 5000
Using iptables
For iptables
, allow incoming traffic on port 5000
using:
sudo iptables -A INPUT -p tcp --dport 5000 -j ACCEPT
Cloud Provider Security Groups
If your server is hosted by a cloud provider (e.g., AWS, Google Cloud, Azure), ensure that the security group or firewall settings permit incoming connections on port 5000
.
Step 5: Add HTTPS Support
To add HTTPS support to your Flask application, you can use a reverse proxy server such as Nginx. Nginx will handle incoming HTTPS requests and forward them to your Flask application running Gunicorn.
Step 5.1: Install Nginx
First, install Nginx on your server:
sudo apt update
sudo apt install nginx
Step 5.2: Obtain an SSL Certificate
Use Let’s Encrypt to obtain a free SSL certificate. Install Certbot to manage the SSL certificates:
sudo apt install certbot python3-certbot-nginx
Step 5.3: Configure Nginx
Create an Nginx configuration file for your Flask application:
sudo nano /etc/nginx/sites-available/flask_app
Add the following configuration to the file:
server {
listen 80;
server_name your_domain.com www.your_domain.com;
location / {
proxy_pass http://127.0.0.1:5000;
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;
}
}
- Replace
your_domain.com
andwww.your_domain.com
with your actual domain name.
Enable the configuration by creating a symbolic link to the sites-enabled
directory:
sudo ln -s /etc/nginx/sites-available/flask_app /etc/nginx/sites-enabled
Test the Nginx configuration:
sudo nginx -t
Reload Nginx to apply the changes:
sudo systemctl reload nginx
Step 5.4: Obtain SSL Certificate with Certbot
Run the following command to obtain and configure the SSL certificate:
sudo certbot --nginx -d your_domain.com -d www.your_domain.com
Follow the prompts to complete the certificate installation.
Step 5.5: Update Nginx Configuration for HTTPS
After obtaining the SSL certificate, Nginx will automatically update the configuration to redirect HTTP to HTTPS. The updated configuration will look like this: sudo nano /etc/nginx/sites-enabled/mywebsite
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name chat.abatecdigital.es;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/chat.abatecdigital.es/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/chat.abatecdigital.es/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Serve your website from /var/www/mysite at the root "/"
root /home/sergio/mdrag/web_example;
index index.html index.htm;
# Location block for your main website at "/"
location / {
try_files $uri $uri/ =404;
}
# Location block for Streamlit app at "/app"
location /app/ {
proxy_pass http://127.0.0.1:8501/;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
rewrite ^/app/(.*) /$1 break;
}
# Location block for Streamlit app at "/app"
location /api/ {
proxy_pass http://127.0.0.1:5000/;
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;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
rewrite ^/app/(.*) /$1 break;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name chat.abatecdigital.es;
# Redirect all HTTP requests to HTTPS
location / {
return 301 https://$host$request_uri;
}
}
Reload Nginx to apply the HTTPS configuration:
sudo systemctl reload nginx
Summary
This guide has provided a comprehensive overview of:
- Setting up a virtual environment for a Flask application.
- Creating a systemd service file to deploy the Flask application using Gunicorn in a production environment.
- Configuring network access to enable external connectivity via port
5000
. - Adding HTTPS support using Nginx as a reverse proxy and Let’s Encrypt for SSL certificates.
Using a production-ready WSGI server such as Gunicorn and configuring it with systemd ensures the Flask application remains reliable, restarts automatically in the event of a failure, and starts on system boot. For enhanced performance and security, the addition of Nginx as a reverse proxy with HTTPS ensures secure communication between clients and the server.