Learn how to run a Flask Python application using Docker with Gunicorn, configure Nginx as a reverse proxy, and secure the server with SSL using Certbot.
Introduction
Flask is widely used for building lightweight APIs and web applications in Python. Docker simplifies deployment by packaging the application and its dependencies into a consistent environment. When combined with Nginx and SSL certificates, Flask applications can run securely and efficiently in production environments.
This guide demonstrates how a Flask application can be containerized using Docker and then served through Nginx with HTTPS enabled using Certbot.
Prerequisites
Before we begin, let’s ensure we have the following in place:
- A Ubuntu 24.04 dedicated server or KVM VPS.
- A basic programming knowledge.
- A domain name pointing A record to server IP.
Learn how to run Flask Python app with Docker, Nginx & SSL
The deployment structure used in this guide:
- Flask application running with Gunicorn inside Docker
- Nginx acting as reverse proxy
- SSL certificate issued using Certbot
- Ubuntu server environment
Prepare the Server Environment
Install required system packages before creating the application environment.
Update the system:
sudo apt update && sudo apt upgrade -y
Install Docker:
Set up Docker's apt repository.
# Add Docker's official GPG key:
sudo apt update
sudo apt install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
Install the Docker packages.
sudo apt install docker-ce -y
Enable and start Docker:
sudo systemctl enable docker
sudo systemctl start docker
Install Nginx and Certbot:
sudo apt install nginx certbot python3-certbot-nginx -y
Check service status:
sudo systemctl status docker
sudo systemctl status nginx
Create the Flask Application
Create a project directory.
mkdir flask-docker-app && cd flask-docker-app
Create the application file.
nano app.py
Example Flask application:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Flask application running inside Docker"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Application characteristics:
- Flask serves the application logic
- Gunicorn will run the application in production
- The container exposes port 5000
Define Python Dependencies
Create a dependency file.
nano requirements.txt
Example dependencies:
flask
gunicorn
Dependency file responsibilities:
- Install Flask framework
- Install Gunicorn production server
- Ensure reproducible builds inside Docker
Create the Dockerfile
Dockerfile defines the environment required for the Flask application.
Create the file:
nano Dockerfile
Example configuration:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
Build process behavior:
- Pulls official Python runtime
- Installs application dependencies
- Copies project files
- Starts the application with Gunicorn
Build the Docker Image
Build the container image from the Dockerfile.
docker build -t flask-app .
Verify the image:
docker images
Expected output should show the newly created image.
Run the Flask Container
Start the container using the built image.
docker run -d -p 5000:5000 --name flask_container flask-app
Container configuration:
- -d runs the container in background
- -p 5000:5000 exposes container port
- --name assigns a readable container name
Verify running container:
docker ps
Configure Nginx as Reverse Proxy
Nginx will forward requests from port 80 to the Flask container.
Create an Nginx configuration file.
sudo nano /etc/nginx/sites-available/flask-app
Example configuration:
server {
listen 80;
server_name example.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;
}
}
Activate the configuration.
sudo ln -s /etc/nginx/sites-available/flask-app /etc/nginx/sites-enabled/
Test Nginx configuration:
sudo nginx -t
Restart Nginx:
sudo systemctl reload nginx
Nginx responsibilities:
- Handle incoming HTTP requests
- Forward traffic to the Docker container
- Manage headers and request forwarding
Configure firewall
We need to add HTTP and HTTPS ports in the firewall.
sudo ufw allow 80,443/tcp
Configure SSL with Certbot
Enable HTTPS using Let's Encrypt certificates.
Run Certbot:
sudo certbot --nginx -d example.com
Certbot process:
- Verifies domain ownership
- Generates SSL certificate
- Automatically updates Nginx configuration
After installation, HTTPS should be active:
https://example.com
Automatic renewal can be verified with:
sudo certbot renew --dry-run
Certbot configuration includes:
- Automatic certificate renewal
- Secure TLS configuration
- Redirect HTTP traffic to HTTPS
Useful Docker Management Commands
Container management commands frequently used in production.
View running containers:
docker ps
View container logs:
docker logs flask_container
Stop container:
docker stop flask_container
Restart container:
docker restart flask_container
Remove container:
docker rm flask_container
Summary
This tutorial demonstrated how a Flask Python application can run inside a Docker container while being served securely through Nginx with HTTPS enabled using Certbot. The process started with preparing a Linux server and installing Docker, Nginx, and Certbot. A simple Flask application was then created and packaged into a Docker image using a Dockerfile with Gunicorn acting as the production application server.

