DEV Community

Cover image for Crafting a Docker Image for Your Flask Web App
tinega
tinega

Posted on

Crafting a Docker Image for Your Flask Web App

Introduction🐋

Docker is a revolutionary containerization platform that streamlines software development and deployment. It encapsulates applications and their dependencies, ensuring consistency across different environments. Docker eliminates the "it works on my machine" problem, promoting collaboration and scalability. Its efficient resource utilization and isolation capabilities make it a vital tool for modern software development.

Prerequisites 🗒

I will assume that you have a basic understanding of python, especially the Flask framework and an understanding of networking ports.

Sample project 🏗️

Project Directory Structure:

hello-flask/
├── app/
│   ├── __init__.py
│   └── app.py
├── requirements.txt
└── Dockerfile

Enter fullscreen mode Exit fullscreen mode

Sample code in app.py file:

from flask import Flask

app = Flask(__name__) # create an instance of our imported Flask class.


@app.route("/")
def home():
    return 'hello flask'

# allows the code to be executed directly as a script
if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')
Enter fullscreen mode Exit fullscreen mode

Official Flask Documentation

Dockerfile 📝

Docker automates image creation by interpreting instructions from a Dockerfile, a text file containing sequential commands required to build a specific image. A Docker image comprises immutable layers, each representing an instruction from the Dockerfile. These layers are arranged in a stack, with each one capturing the incremental changes made compared to the previous layer.
create a Dockerfile with the following instructions:

FROM python:alpine

RUN apk update 
RUN apk add -y python-pip; pip install --no-cache-dir --upgrade pip
WORKDIR /hello-flask
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY /app .
ENTRYPOINT [ "python" ]
CMD [ "app.py" ]

Enter fullscreen mode Exit fullscreen mode

Each instruction break down

FROM python:alpine
It specifies the base image to use, in this case, python:alpine. This image is based on the Alpine Linux distribution and includes Python.

Note that while it's possible to use a Debian-based distro as the base image, it would require manual installation of Python within the image. A python image based on alpine is smaller size compared to other distributions, therefore contributing to a more lightweight and efficient container.

RUN apk update
This updates the package index on the Alpine system using the apk package manager.

RUN apk add -y python-pip; pip install --no-cache-dir --upgrade pip
This installs python-pip using apk and then upgrades pip to the latest version. The -y flag is used to automatically confirm the installation.

WORKDIR /hello-flask
Sets the working directory inside the container to /hello-flask.

COPY requirements.txt .
Copies the requirements.txt file from the build context (where the Dockerfile is located) into the /hello-flask directory in the container.

RUN pip install -r requirements.txt
Installs the Python packages listed in requirements.txt using pip. This is typically done in a separate step to take advantage of Docker layer caching.

COPY /app .
Copies the contents of the /app directory from the build context into the current working directory /hello-flask in the container.

ENTRYPOINT [ "python" ]
Specifies the default executable when the container starts. In this case, it sets the default executable to Python.

CMD [ "app.py" ]
Provides default arguments for the ENTRYPOINT. When the container is run, it will execute python app.py by default.

Building your docker image 🔨

The docker build command builds Docker images from a Dockerfile and a context.

docker image build -t myrepo/hello-flask .

This will build an image with the repository name as myrepo/hello-flask and a tag of latest is applied by default.
The -t option allows you to tag your Docker image with a specific name and optionally a tag.
Tags are typically appended to the image name by specifying them following a colon.

The dot at the end of the command specifies the build context. The build context is the path to the directory containing the Dockerfile and any files needed for the build process. In this case, it's set to the current directory

Running a container from your image 📦

The docker container run command runs a command in a new container, pulling the image if needed and starting the container.

docker container run --rm -p 5000:5000 myrepo/hello-flask

replace myrepo with your docker hub username or if you don't intend to upload to image just use name of the image.e.g

docker container run --rm -p 5000:5000 hello-flask

--rm
This flag removes the container automatically after it stops running. It helps to keep the system clean by avoiding the accumulation of unused containers.

-p 5000:5000
This flag maps the port 5000 from the host to the port 5000 on the container. It allows communication between the host machine and the running container through this specified port.

myrepo/hello-flask
This is the name of the Docker image used to create the container. It's assumed that you have an image named hello-flask in the myrepo repository.

another useful OPTION to add to the docker container run command is:
--detach or -d this runs the container in the background and prints its ID.

You should be able to view a webpage by visiting http://localhost:5000

Pushing your image to docker hub 🚀

Before trying to push your image make sure to login in the docker CLI using docker login with your docker hub credentials.

Use docker image push to upload your images to the Docker Hub registry or to a self-hosted one.

docker image push myrepo/hello-flask

Other Commands

docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] -- create an image tag
docker image ls -- lists images in your local machine.
docker container ls or docker ps [OPTIONS] -- lists containers.
docker container stop [container id | container name] -- stop a running container
docker container rm [container id | container name] -- remove container
docker image prune [OPTIONS] -- remove unused images.

More Commands - Documentation

Images Vs Containers

An image represents the application we intend to execute, while a container is an instance of that image running as a process.

Think of a Docker image as a recipe or a blueprint for creating a specific environment, and a Docker container as a ready-made dish prepared using the recipe (image).

Top comments (0)