Jenkins Project: Building CI/CD Pipeline for Scalable Web Applications
Docker
Building a Custom Docker Image
In this guide, you'll learn how to build a custom Docker image for a Flask application and push it to Docker Hub. We will containerize a simple Flask app that manages tasks and walk through creating the Dockerfile, building the image, and deploying it.
Application Overview
Our sample Flask application (app.py) manages tasks with basic operations. Below is an excerpt of the code:
from flask import Flask, render_template, request
app = Flask(__name__)
# A dictionary to store tasks with an ID
tasks = {}
task_id_counter = 1
@app.route('/', methods=['GET', 'POST'])
def index():
global task_id_counter
response_text = ""
if request.method == 'POST':
if 'add_task' in request.form:
task_content = request.form.get('task_content')
if task_content:
tasks[task_id_counter] = task_content
task_id_counter += 1
elif 'delete_task' in request.form:
task_id_to_delete = int(request.form.get('task_id_to_delete'))
tasks.pop(task_id_to_delete, None)
return render_template('index.html', tasks=tasks)
Creating the Dockerfile
To containerize the Flask application, create a Dockerfile that includes instructions for setting the base image, copying your source code, installing dependencies, exposing the necessary port, and starting the application.
Below is an example Dockerfile for our Flask app:
FROM python:3.12.0b3-alpine3.18
COPY /application
WORKDIR /application
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]
This Dockerfile performs the following actions:
- Base Image: Uses a Python image based on Alpine Linux, tagged as version 3.12.0b3‑alpine3.18.
- Copying Code: Transfers your application source code into the container.
- Setting the Working Directory: Switches context to
/application
for subsequent commands. - Installing Dependencies: Copies
requirements.txt
and installs the necessary Python packages. - Exposing Port 5000: Documents the port on which the container will listen.
- Running the Application: Executes the command to start the Flask application.
Note
The EXPOSE
instruction is for documentation purposes only and does not publish the port. Use the -p
flag to map container ports to the host, e.g., docker run -p 5000:5000 my-flask-app:v1
.
Selecting the Appropriate Base Image
Since this application utilizes Python, we selected an Alpine-based Python image available on Docker Hub for its reduced size and efficiency. Searching for "python" on Docker Hub provides multiple options, including slim and Alpine variants.
Copying Application Files
The Dockerfile uses the COPY
command to add your application files and dependency file into the image. Here’s an illustrative snippet:
FROM python:3.12.0b3-alpine3.18
COPY /application
COPY hello.txt /absolute/path
COPY hello.txt relative/to/workdir
This demonstrates the flexibility of the COPY
command, allowing files to be added either to an absolute path or relative to the current working directory. Following these commands, the Dockerfile sets up the working directory, installs dependencies, exposes the application port, and defines the startup command.
Building the Docker Image
With your Dockerfile ready, build the image by running the following command from the directory containing your Dockerfile. The -t
flag tags the image:
docker build -t my-flask-app:v1 .
This command processes each instruction in the Dockerfile and generates a Docker image tagged my-flask-app:v1
.
Running the Container
After building the image, you can verify it by listing all Docker images:
docker image ls
To run the container, use the following command:
docker run my-flask-app:v1
The terminal output should confirm that your Flask application is running on port 5000. Press Ctrl+C to stop the container.
Pushing the Image to Docker Hub
After creating your Docker image, the next step is to push it to a repository like Docker Hub for easy deployment and team access.
Logging in and Creating a Repository
First, log into Docker Hub using:
docker login
After entering your credentials, create a new repository on Docker Hub (for example, "jenkins-flask-app").
Retagging and Pushing the Image
Docker Hub requires images to be tagged with the format: username/repository:tag. Retag your image using your Docker Hub username:
docker image tag my-flask-app:v1 sanjeevkt720/jenkins-flask-app:v1
Verify the new tag by listing your images:
docker image ls
Now, push the image to Docker Hub:
docker push sanjeevkt720/jenkins-flask-app:v1
The terminal should display confirmation messages indicating that the image layers and digest have been successfully pushed.
Updating the Application and Creating New Versions
As your application evolves, update the code and, if necessary, adjust the Dockerfile instructions. Build a new version of the image with an updated tag. For example, after updating the application, rebuild the image as version three:
Dockerfile remains unchanged:
FROM python:3.12.0b3-alpine3.18
COPY /application
WORKDIR /application
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]
Rebuild the image:
docker build -t sanjeevkt720/jenkins-flask-app:v3 .
Confirm the new image tag:
docker image ls
Push the updated image to Docker Hub:
docker push sanjeevkt720/jenkins-flask-app:v3
A successful push will indicate that the new image version is available in your Docker Hub repository.
Additional Considerations
- Port Mapping: To publish a container port on the host, use the
-p
flag withdocker run
(e.g.,docker run -p 5000:5000 sanjeevkt720/jenkins-flask-app:v1
). - Alternative Registries: While Docker Hub is widely used, repositories on AWS, Azure, and GCP also support similar tagging and push commands.
By following these steps, you've successfully containerized your Flask application, built custom Docker images, and deployed them to Docker Hub for streamlined delivery and collaboration.
Resources
Resource Type | Use Case | Example Command |
---|---|---|
Docker Build | Building a Docker image from your Dockerfile | docker build -t my-flask-app:v1 . |
Docker Run | Running a container from the image | docker run -p 5000:5000 my-flask-app:v1 |
Docker Push | Pushing your image to a repository | docker push sanjeevkt720/jenkins-flask-app:v1 |
For more detailed documentation, visit these links:
Happy containerizing!
Watch Video
Watch video content