How to Containerize a Redis Flask Application using Docker Compose
Tags: docker, devops, python, kubernetes
Published: 2023-07-11 18:07:02

[Flask](https://flask.palletsprojects.com/en/2.2.x/) is an open-source Python micro framework for building web applications. It is implemented on implemented on Werkzeug and Jinja2. [Redis](https://redis.io/) is a  vibrant open source in-memory data store platform. Developers use Redis as a message broker, database, streaming engine and for application caching. 

We will use Redis for caching. Caching is a computing technique that enables applications to temporarily store data, files, and login details in the Random Access Memory. It enable faster retrievals of that data and the application will load faster.

In this tutorial, We will build a sample Python Flask application and implement Redis for caching. We will then containerize the Redis Flask application using [Docker Compose](https://docs.docker.com/compose/). Docker Compose is a powerful Docker tool for creating and running multi-container Docker applications. Our application will have two containers. The first container will host the Flask application. The other container will be for Redis caching. Docker Compose will run the two containers as a single application. Lets get started

### Prerequisites
Before you get started, you must understand [Docker](https://www.docker.com/). You also need the following set up in your working machine:

- [Vs Code](https://code.visualstudio.com/) for code editing.
- [Python](https://www.python.org/) installed.
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) set up.

### Buidling a sample Python Flask application
We build a sample Python Flask application and implement Redis for caching. Lets install Flask and Redis using the following `pip` commands in your terminal:

```pip
pip install flask
pip install redis
```
After the installation process, create a folder named `flask-redis`. In the folder, create a new file named `app.py`. Open the file and add the following code snippet:

```python
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    redis.incr('hits')
    counter = str(redis.get('hits'),'utf-8')
    return "Welcome to this webapage!, This webpage has been viewed "+counter+" time(s)"

if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)
```
The Flaska application will use Redis caching to show the number of times the webpage have been viewed. To run the application, `cd` into the `flask-redis` folder and run the following `python` command:

```python 
python app.py
```
The command will start and run the Flask web application:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9u9xvhl8bce5y3nrmhmd.png)

You can access the web application on `http://127.0.0.1:5000/`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6z3ud4owigfrgtcrq3q0.png)

### Containerizing the Redis Flask application
We will use Docker Compose to containerize the Redis Flask application. With Docker Compose, you create a YAML file to add and configure your application's containers as services. Our Docker Compose file will have two services: Flask Service and Redis Service. When creating the Docker Compose file, the Flask service will depend on the Redis service. 

The Docker Compose YAML file will also define the container volumes, port mapping, container names and the Dockerfiles for building the image.Docker Compose will execute the specified Dockerfiles and build the Docker containers. A [Dockerfile](https://docs.docker.com/engine/reference/builder/) is a text file with no file extension that contains all the commands and instructions that the Docker Engine uses to automatically build a Docker image. 

We will only require one Dockerfile to build the Python Flask application image. Implementing Redis container for caching does not require a Dockerfile because we will use the official [Redis Docker image](https://hub.docker.com/_/redis) from Docker Hub. The official image also known as the base/parent image. We will pull the Redis image from Docker Hub and use it to build a Redis Container without making any changes to the Docker image. We will also create a `requirements.txt` file in the `flask-redis` folder. 

#### Creating a `requirements.txt` file
This file will contain the dependancies, libraries and tools for creating our application. Our application requires Flask for building the web application and Redis for caching. In the `flask-redis` folder, create a `requirements.txt` file and add the following content:

```txt
flask
redis
```
We will add an instruction in the Dockerfile to install these two libaries in Python Flask application Docker image. Let's create a `Dockerfile` for the Python Flask application.

#### Dockerfile for the Python Flask application
Docker will read the instructions written in the Dockefile and build a Docker image. Dockerfiles differ depending on the application you are building. In the `flask-redis` folder, create a new `Dockerfile` and add the following content:

```docker
#The Flask application container will use python:3.10-alpine as the base image
FROM python:3.10-alpine

#This command will create the working directory for our Python Flask application Docker image
WORKDIR /code

#This command will copy the dependancies and libaries in the requirements.txt to the working directory
COPY requirements.txt /code

#This command will install the dependencies in the requirements.txt to the Docker image
RUN pip install -r requirements.txt --no-cache-dir

#This command will copy the files and source code required to run the application
COPY . /code

#This command will start the Python Flask application Docker container
CMD python app.py
```

Now that we have created the Dockerfile, we now need to create a `docker-compose.yml` file which will configure the application's containers as services. It will also add all the configurations required to run the two Docker containers.

### Creating a `docker-compose.yml`
The `docker-compose.yml` will simply the process of creating and running the Docker containers. Using a single command you can run `docker-compose.yml` to launch all the containers at once. Docker Compose can work in all stages of application development to deployment. It also has other commands that helps in the management of Docker Containers such as viewing the status of created services and stopping the running services.

In the `flask-redis` folder, create a `docker-compose.yml` file and add the following two services:

1. Redis Service 
To create a `Redis` service, add the following code in the created file:

```docker-compose
services:
   redis: 
     image: redislabs/redismod
     container_name: redis
     ports:
       - '6379:6379' 
```
The code above will create a `redis` service. This service will use the `redislabs/redismod` Docker image from Docker Hub to build the Docker Container. The `container_name` is `redis`. The `redis` container will run on port `6379`. 

2. Flask Service
To create a `Flask` service, add the following code in the created file:

```docker-compose
   flask:
        build: .
        container_name: flask
        ports:
            - "5000:5000"
        volumes:
            - .:/code
        depends_on:
            - redis
```
The code above will create a `flask` service that depends on the `redis` service to run. This service will use the Docker file in the `flask-redis` folder Docker image to build the Docker Container. The `container_name` is `flask`. The `flask` container will run on port `5000`. The code will also create container volume in the working directory. A container will map the `flask-redis` folder to the container working directory. When a file change is made in the `flask-redis` folder, it will be automatically be updated in the container working directory. It ensures the container is always updated.

The final `docker-compose.yml` file will be as shown below:

```docker-compose
services:
   redis: 
     image: redislabs/redismod
     container_name: redis
     ports:
       - '6379:6379' 
   flask:
        build: .
        container_name: flask
        ports:
            - "5000:5000"
        volumes:
            - .:/code
        depends_on:
            - redis
```

After adding the two services to the file, the next step is to use a single command you can run `docker-compose.yml` to launch all the containers at once.

#### Launching the two containers at once
To launch the two containers at once, use the following `docker-compose` command:

```docker-compose
docker-compose up
```
The command will build and start the two Docker containers as shown below:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3i4o2ywcq8wtc03w3ly4.png)

You can also access the web application on `http://127.0.0.1:5000/`.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ac7xx079j9e02niwhsip.png)

From the image above, we can see the Containerized Flask application is running with Redis caching. Refresh the webpage to increase the number of times the webpage has been viewed.

### Conclusion
In this tutorial you have lerned how to containerize a Redis Flask application using Docker Compose. We started by build a sample Python Flask application and implemented Redis for caching. We then created a Dockerfile that was used to containerized the Python Flask application. We created a `docker-compose.yml` for adding and configuring the application's containers as services. Finally, we launched the two containers at once using `docker-compose up` and accessed the application on http://127.0.0.1:5000/.

The application in this tutorial is a simple application used for demonstration purpose. You can use your own Flask application to implement the concepts of this tutorial. Hope this tutorial helps you in your DevOps journey and Thanks for Reading!