Wednesday, April 29, 2026

Creating a Custom Python Application Image and Deploying to Docker

This ties in well with the previous infrastructure studies I’ve been completing, and I’d like to be able to combine both skills to build out a cloud-based deployment pipeline for my Python projects.

Get Michael Rodgers’s stories in your inbox

Join Medium for free to get updates from this writer.

To begin with, I’ve created a local development Docker host, with Jenkins installed for CI/CD, and Prometheus and Grafana installed for monitoring. My next step is following the Docker documentation for Pythonwhich details deploying a Flask application to a container. I’ve listed the steps I’ve taken below.

Steps Taken

Prepare Repository and Minimal Flask Server

I’ll be using the GitLab repo that I’ve previously stored files relating to this Docker host, creating a new branch for this project.

  • mkdir hello-py && cd hello-py to create a folder within the file structure to hold project files
  • mkdir server && cd server && touch main.py to create the code file structure and Flask server entry point, entering the following code:
from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
return print("hello, py!")


if __name__ == "__main__":
app.run(debug=True)
  • Within the hello-py/server folder, open a terminal instance and create a Python virtual environment, selecting relevant OS specific commands:
# Linux & macOS
python3 -m venv .venv
source .venv/bin/activate

# Windows
py -3 -m venv .venv
.venv\scripts\activate
  • Following this, in VSCode, press ⇧⌘P and select the Python interpreter
  • python -m pip install --upgrade pip within VSCode’s .venv terminal to update pip
  • python -m pip install flask to install Flask
  • pip freeze > requirements.txt to output the Python package requirements
  • I added .venv to the .gitignore file to prevent the folder from being committed to the repo
  • python -m flask run to start the server at URL http://localhost:5000

Create a Dockerfile

  • touch Dockerfile within the hello-py directory create a file to build the custom Docker image
  • # syntax=docker/dockerfile:1 specify the Dockerfile syntax
  • FROM python:3.9.13-slim-buster specify the base Python image to use
  • WORKDIR /hello-py create a working directory for the subsequent commands
  • COPY requirements.txt requirements.txt copy the pip requirements file
  • RUN pip3 install -r requirements.txt use the copied requirements file to install pip dependencies
  • COPY . . will copy the Python project files into the /hello-py image directory
  • CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"] supply the command to run that will launch the server, and make it accessible outside of the container

The final Dockerfile code should look like this:

# syntax=docker/dockerfile:1

# base python image for custom image
FROM python:3.9.13-slim-buster

# create working directory and install pip dependencies
WORKDIR /hello-py
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt

# copy python project files from local to /hello-py image working directory
COPY . .

# run the flask server
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]

Build the Image

  • docker build --tag hello-py . in the local file’s terminal to build the image using the Dockerfile
Custom Python server image built with Dockerfile
Custom Python server image built with Dockerfile

Testing the Image in a Local Container

  • docker run -d -p 5001:5000 hello-py on my local machine to test that the image was built successfully

I’m using an external port of 5001 on the container on my local machine as I have been using port 5000 for running the Flask server through VSCode’s terminal, and want to make sure there are no conflicts. When we move the image to the remote Docker host I’ll use an external port of 5000

Container deployed from custom image on local computer
Container deployed from custom image on local computer

Push to Docker Hub and Deploy to Remote Container

  • docker login --username=mjrod run this if required to connect CLI to Docker Hub account
  • docker tag hello-py mjrod/hello-py tag the image with your Docker Hub username: <username>/<image-name>
  • docker push mjrod/hello-py to push a new repository to Docker Hub to store the image
Image pushed from CLI to Docker Hub successfully
Image pushed from CLI to Docker Hub successfully

After this, log into the remote Docker host using SSH and run the following

  • docker pull mjrod/hello-py:latest to pull the previously uploaded image from Docker Hub
  • docker run -d -p 5000:5000 --name=hello-py mjrod/hello-py to launch the container
Containers deployed on remote Docker host
Containers deployed on remote Docker host

Navigate to http://<remote-docker-ip>:5000 to see the Python application running in the remote container

Next Steps

  1. Begin coding my Python application — now that I have the ability to package up my Python code and deploy it to a container, I’d like to begin building high-quality web applications to cement both my programming and infrastructure learnings.
  2. Build a Jenkins pipeline to automate the rebuilding phases for each Docker images — each time I make code changes, the steps outlined in this document will need to be repeated to make the images reflect the code base. I’d like to link my Gitlab repo and my Docker host using Jenkins to automate some of this task away.

No comments:

Post a Comment

Build and Deploy Dockerize Python Application to Azure Container Instances (ACI) using Azure DevOps

  As a software Engineer, I would like to deploy my Dockerized Python Application to Azure Container Instance (ACI) using Azure DevOps so th...