Run Flask Python App with Docker, Nginx & SSL

By Anurag Singh

Updated on Mar 13, 2026

Run Flask Python App with Docker, Nginx & SSL

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.