How to Deploy a Flask Application with Gunicorn, Nginx, and SSL
Deploying a Flask application on a production server requires setting up Gunicorn as the application server, Nginx as the reverse proxy…
Deploying a Flask application on a production server requires setting up Gunicorn as the application server, Nginx as the reverse proxy, and implementing SSL for secure HTTPS connections. This guide walks you through the step-by-step process of deploying a Flask application using these tools, including configuration for HTTPS redirection and SSL setup with Certbot.
Overview of Tools
- Flask: A lightweight web framework for Python.
- Gunicorn: A Python WSGI HTTP server that handles client requests for the Flask app.
- Nginx: A powerful HTTP server and reverse proxy to serve as the public-facing web server.
- Certbot: A tool to obtain free SSL certificates from Let’s Encrypt, ensuring secure connections.
Step 1: Create and Configure the Flask Application
- Set Up the Flask App: Start by creating a project directory and setting up a virtual environment:
mkdir ~/myapp
cd ~/myapp
python3 -m venv venv
source venv/bin/activate
pip install flask gunicorn2. Create a Sample Flask App: Create a file named app.py with a simple route:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello, Flask with Gunicorn and Nginx!"
if __name__ == "__main__":
app.run()3. Test Locally: Run the app locally to make sure it works:
python app.pyNavigate to http://127.0.0.1:5000 to confirm the app is running correctly.
Step 2: Set Up Gunicorn as the Application Server
- Run the App with Gunicorn: Use Gunicorn to serve the app on a specific port:
gunicorn -w 3 -b 127.0.0.1:8000 app:appTest by visiting http://127.0.0.1:8000.
2. Set Up Gunicorn as a Systemd Service: To ensure the app starts on reboot, create a Systemd service for Gunicorn:
sudo nano /etc/systemd/system/myapp.serviceAdd the following configuration to this file:
[Unit]
Description=Gunicorn instance to serve myapp
After=network.target
[Service]
User=youruser
Group=www-data
WorkingDirectory=/home/youruser/myapp
Environment="PATH=/home/youruser/myapp/venv/bin"
ExecStart=/home/youruser/myapp/venv/bin/gunicorn -w 3 -b 127.0.0.1:8000 app:app
[Install]
WantedBy=multi-user.target- User: Replace
youruserwith your actual server username. - WorkingDirectory and Environment: Point to the project directory and virtual environment.
Enable and start the service:
sudo systemctl start myapp
sudo systemctl enable myappStep 3: Install and Configure Nginx
- Install Nginx:
sudo apt update
sudo apt install nginx2. Set Up Nginx Configuration for Your Flask App: Create a new Nginx configuration file:
sudo nano /etc/nginx/sites-available/myappAdd the following content to configure Nginx as a reverse proxy and enforce HTTPS:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://yourdomain.com$request_uri;
}
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://127.0.0.1:8000;
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
yourdomain.com: Use your actual domain name. - The first server block handles HTTP traffic and redirects it to HTTPS.
- The second server block configures HTTPS with SSL certificates and proxies requests to Gunicorn.
3. Enable the Configuration: Link this configuration to the sites-enabled directory:
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabledTest and reload Nginx:
sudo nginx -t
sudo systemctl reload nginxStep 4: Set Up SSL with Certbot
- Install Certbot (if not already installed):
sudo apt install certbot python3-certbot-nginx2. Obtain and Configure SSL Certificate: Run Certbot to obtain the SSL certificate and automatically configure Nginx:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.comCertbot will modify the Nginx configuration to include SSL directives.
3. Verify Auto-Renewal: Certbot is set to automatically renew certificates. To check, use:
sudo certbot renew --dry-runStep 5: Testing and Verification
- Test HTTPS Redirect: Visit
http://yourdomain.comand confirm it redirects tohttps://yourdomain.com. - Check for Secure Connection: Ensure your browser displays a secure connection (lock icon) for HTTPS.
- Check Logs for Errors: If any issues arise, check the logs for debugging:
sudo journalctl -u myapp
sudo tail -f /var/log/nginx/error.logSummary
This guide has provided a comprehensive setup to deploy a Flask application with:
- Gunicorn: Efficiently handling client requests.
- Nginx: Acting as a reverse proxy and serving secure connections.
- Certbot: Providing SSL for secure HTTPS connections.
- HTTP to HTTPS Redirect: Ensuring all traffic goes through a secure connection.
This configuration will make your Flask app production-ready with secure, reliable, and scalable infrastructure.