Logo

dev-resources.site

for different kinds of informations.

Optimising Flask Dockerfiles: Best Practices for DevOps and Developers

Published at
1/2/2025
Categories
flask
docker
devops
python
Author
pravesh_sudha_3c2b0c2b5e0
Categories
4 categories in total
flask
open
docker
open
devops
open
python
open
Author
25 person written this
pravesh_sudha_3c2b0c2b5e0
open
Optimising Flask Dockerfiles: Best Practices for DevOps and Developers

đź’ˇ Introduction

Welcome to the world of DevOps! 🚀 Today, we’re diving into an essential skill for any DevOps engineer: optimizing Dockerfiles for Flask applications. While beginner DevOps engineers often focus on mastering basic Dockerfile syntax, experienced engineers know that true expertise lies in optimization—crafting Dockerfiles that are efficient, secure, and production-ready.

In this blog, we’ll walk through the process of building a simple Flask application. First, we’ll create a basic Dockerfile, and then we’ll refine it into an optimized version, comparing the two to understand the difference. Whether you're a beginner or looking to sharpen your Dockerfile skills, this guide has something for everyone.

Let’s get started! 🛠️


đź’ˇ Pre-Requisites

Before we dive into writing and optimizing Dockerfiles for a Flask application, ensure you have the following prerequisites in place:

  1. Basic Understanding of Flask

    Familiarity with creating a simple Flask application will help you follow along seamlessly.

  2. Docker Installed

    Make sure Docker is installed and running on your system. You can download it from the Docker website.

  3. Python Environment Setup

    Python 3.x installed on your system, along with pip for managing Python packages.

  4. Code Editor

    Use any code editor of your choice, such as Visual Studio Code, PyCharm, or Sublime Text.

  5. Flask Installed

    Install Flask in your Python environment using the command:

   pip install flask
Enter fullscreen mode Exit fullscreen mode
  1. Sample Flask Application Have a simple Flask application ready or be prepared to create one as we proceed in the tutorial.

đź’ˇ Creating the Flask Application

To start, we’ll create a simple Flask application and prepare it for containerization. Follow these steps:

  1. Create the Project Directory

    Make a directory named basic-flask and navigate into it.

  2. Create the Flask Application

    Inside the basic-flask directory, create a file named app.py with the following content:

   from flask import Flask

   app = Flask(__name__)

   @app.route("/")
   def HelloWorld():
       return "Hello World"

   if __name__ == "__main__":
       app.run()
Enter fullscreen mode Exit fullscreen mode

You can run this application using the command:

   python3 app.py
Enter fullscreen mode Exit fullscreen mode

Open your browser and go to http://localhost:5000. You should see Hello World displayed on the web page.

Image description

  1. List the Dependencies To containerize the app, we first need to specify the required Python modules. Create a requirements.txt file by running:
   pip3 freeze > requirements.txt
Enter fullscreen mode Exit fullscreen mode

đź’ˇ Creating Dockerfiles

Now, let’s create two versions of Dockerfiles: a basic version and an optimized version.

Basic Dockerfile

The basic Dockerfile is straightforward but lacks efficiency and security optimizations:

FROM python:3.9-slim

WORKDIR /app

COPY . /app

RUN pip install -r requirements.txt

CMD ["python3", "app.py"]
Enter fullscreen mode Exit fullscreen mode

This Dockerfile is functional but leaves room for improvement in caching, size optimization, and security practices.

Optimized Dockerfile

The optimized Dockerfile follows multi-stage builds and incorporates best practices for efficiency, security, and modularity:

# syntax=docker/dockerfile:1.4

# Stage 1: Build dependencies
FROM --platform=$BUILDPLATFORM python:3.10-alpine AS builder

WORKDIR /code

# Install build dependencies and cache pip files for efficiency
COPY requirements.txt /code
RUN --mount=type=cache,target=/root/.cache/pip \
    pip3 install --prefix=/install -r requirements.txt

COPY . /code

# Stage 2: Development environment setup
FROM python:3.10-alpine AS dev-envs

WORKDIR /code

# Copy application files and installed dependencies
COPY --from=builder /install /usr/local
COPY . /code

# Install additional tools for development (e.g., Git, Bash)
RUN apk update && apk add --no-cache git bash

# Create a non-root user for better security
RUN addgroup -S docker && \
    adduser -S --shell /bin/bash --ingroup docker vscode

# Set entrypoint and command for development purposes
ENTRYPOINT ["python3"]
CMD ["app.py"]

# Stage 3: Production-ready image
FROM python:3.10-alpine AS final

WORKDIR /app

# Copy only necessary application files and dependencies
COPY --from=builder /install /usr/local
COPY app.py /app

ENTRYPOINT ["python3"]
CMD ["app.py"]
Enter fullscreen mode Exit fullscreen mode

đź’ˇ Building the Dockerfiles

Now that we have created both Dockerfiles, it’s time to build Docker images and observe the differences in their sizes. Follow these steps:

Build the Image from the Basic Dockerfile

  1. Ensure the content of the basic Dockerfile is saved in a file named Dockerfile.
  2. Build the image using the following command:
   docker build -t basic-dockerfile .
Enter fullscreen mode Exit fullscreen mode

Image description

Build the Image from the Optimized Dockerfile

  1. Save the content of the optimized Dockerfile in a separate file named Dockerfile.
  2. Build the image using this command:
   docker build -t optimised-dockerfile .
Enter fullscreen mode Exit fullscreen mode

Image description

Compare the Built Images

Once the images are built, list all Docker images using:

docker images
Enter fullscreen mode Exit fullscreen mode

Image description

You should notice a significant difference in the image sizes:

  • Basic Dockerfile Image: Approximately 177MB
  • Optimized Dockerfile Image: Approximately 59.2MB

Why the Optimized Image is Smaller

  • Lightweight Base Image: The optimized Dockerfile uses python:3.10-alpine, which is significantly smaller than python:3.9-slim.
  • Multi-Stage Build: Unnecessary build dependencies are excluded from the final image, keeping it minimal.
  • Efficient Caching: The use of caching for pip installations avoids redundant downloads and reduces image layers.

đź’ˇ Conclusion

Optimizing Dockerfiles is a crucial skill for DevOps engineers aiming to create efficient, secure, and production-ready containers. In this blog, we explored how to build a simple Flask application, containerize it using a basic Dockerfile, and then refine it with an optimized Dockerfile.

The differences in image size and structure demonstrate the impact of best practices like using multi-stage builds, lightweight base images, and caching mechanisms. While the basic Dockerfile served its purpose, the optimized version provided a leaner, more secure, and performant container, highlighting the importance of thoughtful design in containerization.

As you continue your DevOps journey, always strive to enhance your Dockerfiles by incorporating optimizations, considering security, and minimizing overhead. A well-optimized Dockerfile not only saves time and resources but also ensures smoother deployments and scalability in production.

Now it’s your turn—try applying these techniques to your own projects and see the difference optimization makes! 🚀

🚀 For more informative blog, Follow me on Hashnode, X(Twitter) and LinkedIn.

Happy coding and automating! 🚀

flask Article's
30 articles in total
Favicon
Deploy your Flask API on GCP Cloud Run 🚀
Favicon
RESTful GET and POST Requests: A Beginners Guide
Favicon
Flask Routes vs Flask-RESTful Routes
Favicon
Bringing Together Containers & SQL
Favicon
Creating a Local Environment to Operate GCS Emulator from Flask
Favicon
Optimising Flask Dockerfiles: Best Practices for DevOps and Developers
Favicon
A beginners guide to Constraints and Validations in Flask, SQLAlchemy
Favicon
Deploying Flask-based Microservices on AWS with ECS Service Connect
Favicon
FastAPI + Uvicorn = Blazing Speed: The Tech Behind the Hype
Favicon
CRUD With Flask And MySql #2 Prepare
Favicon
CRUD With Flask And MySql #1 Introduction
Favicon
Building an Anemia Detection System Using Machine Learning đźš‘
Favicon
Como usar WebSockets em Flask (How to use WebSockets in Flask)
Favicon
Setup Celery Worker with Supervisord on elastic beanstalk via .ebextensions
Favicon
How to create a simple Flask application
Favicon
Flask
Favicon
Building and Testing the Gemini API with CI/CD Pipeline
Favicon
Crossing the Line before the Finish Line. Also the line before that.
Favicon
Mastering Python Async IO with FastAPI
Favicon
Webinar Sobre Python e InteligĂŞncia Artificial Gratuito da Ebac
Favicon
Is Flask Dead? Is FastAPI the Future?
Favicon
422 Error with @jwt_required() in Flask App Deployed on VPS with Nginx
Favicon
WSGI vs ASGI: The Crucial Decision Shaping Your Web App’s Future in 2025
Favicon
Building a Real-Time Flask and Next.js Application with Redis, Socket.IO, and Docker Compose
Favicon
Carla Simulator 2 : Welcome to the Ride 🚗🏍️
Favicon
Python: A Comprehensive Overview in One Article
Favicon
Understanding Authentication: Session-Based vs. Token-Based (and Beyond!)
Favicon
Building RESTful APIs with Flask
Favicon
Validatorian
Favicon
LumaFlow

Featured ones: