paint-brush
Mastering Multi-Container Management: Deploying a Full-Stack Flask App with Docker Composeby@nyartech
225 reads

Mastering Multi-Container Management: Deploying a Full-Stack Flask App with Docker Compose

by Nyartech_December 20th, 2023
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Explore seamless multi-container management with Docker Compose, deploying a full-stack Flask app.
featured image - Mastering Multi-Container Management: Deploying a Full-Stack Flask App with Docker Compose
Nyartech_ HackerNoon profile picture


When working with microservices in Docker, it’s a best practice to separate the services into different containers. The interdependence makes it easier for developers to coordinate and scale applications, accelerating time to market for new features.


For your application to function, you must manage and run multiple containers simultaneously. That's where Docker Compose comes in!


Using this tutorial, let’s learn how to deploy a full-stack Flask app with a front and back end. You will also learn what Docker Compose is and how to use it in Container management.


What Is Docker Compose?

Docker Compose is a tool used to deploy and manage multiple Docker containers. It manages each container in isolation but coordinates interactions with each other.


With Docker Compose, you can run an entire application stack by defining its volumes, services, and networks in a single YAML file.


Docker Compose uses a scripting language called YAML, an XML-based language, to write the manifest. With YAML, you can run several services using only one command.

Getting Started With Docker Compose

You will build an application with two microservices, a front, and a backend. Then, use Docker Compose to connect the containers and run the application.



Skip to step 4 if you have containerized your microservices.


Prerequisites

To create this project successfully, you will need the following:

  • Familiarity with Docker containers
  • Familiarity with APIs


1. Create an Application

Create an application with two or more microservices. I created a Flask app with two microservices, a front end and a back end. If you don't want to create an app from scratch, fork this Flask application to get started.

2. Build Docker Images for Each Microservice

Use Dockerfiles to create Images for each microservice. Use the following command:

touch quote_disp/Dockerfile 

touch quote_gen/Dockerfile 


The quote_disp folder is the front end, and the qoute_gen hosts the app's backend.

In the Dockerfiles, define the commands needed to build your application.


The application file structure should include the new Docker files.


Project file structure


In the Dockerfiles, add instructions to build and run the application in Docker containers. For my Flask App, it appears like this:

FROM python:3.8-slim-buster
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT [ "python" ]
CMD [ "app.py" ]


Then, build the images using the following commands:

docker build -t quote-gen-service ./quote_gen


docker build -t quote-disp-service ./quote_disp


Run docker images command on the terminal to ensure that the image generation was a success.

Created Docker images

3. Run the Docker Containers

Now that you have the images run the Images to get the containers running. Use docker run [OPTIONS] IMAGE [COMMAND] [ARG...] to run the containers.

docker run -d --name quote-gen-container -p 5000:5000 quote-gen-service
docker run -d --name quote-disp-container -p 5001:5001 quote-disp-service


The above code -d represents the detached mode, which means you run the containers in the background. Next --name is the container and -p is the port number exposing the container.


The port number has the syntax HOST_PORT: CONTAINER _PORT.

Ports are not infinite. They are represented as 16-bit unsigned integers, meaning they go up to 65535. In general, just use any value between 1024 and 65535; values below 1023 are referred to as system ports and are used by other applications.


Run docker ps to view the running containers.


Click on the following prompt to view the application on the browser.

You should see both applications on the browser :

Application on browser

Did you notice that you cannot access the other application via the link on the front end? This is because the containers cannot communicate. To help them communicate, we have to create a network using Docker Compose.


First, stop and remove all running containers with the following commands:

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

4. Create a Docker Compose Manifest

Docker Compose makes it easier to manage multiple containers. Compose creates the necessary networks and connectivity between containers defined in the manifest file. Let's create a Docker Compose manifest to orchestrate our services.


In the root folder, create a docker-compose.yml file and add the following information: version:

Version"3.7"
services:  
  web1: 
    build: ./quote_gen 
    ports: 
      - "5000:5000" 
  web2:  
    build: ./quote_disp
    ports:  
      - "5001:5001" 
    depends_on:
      - web1  


In the above manifest, the version refers to the Docker Compose version you are using. Services refer to the networks you are creating. In this case, you are using the web service names web1 and web2 instead of a container name.


Using the service name allows Docker Compose to handle load balancing between multiple replicas of the same container during scaling. Both services will communicate under ports 5000:5000 and 5001:5001. Web 2 service depends on the web1 service.


Build refers to the container image used to build the containers during deployment.

5. Run Docker Compose

Run the following command to start Docker Compose:

docker compose up -d


The result is that Docker compose spins up the containers, creating new networks.


Docker Compose creates the container services


Next, navigate to the ports area on the terminal and click the network part to see the applications on the browser.


View Ports on Terminal


Notice that you can now access the application's backend via the link on the front end. Docker Compose automatically linked the two containers.


Application Front end

Application Backend


The containers are now communicating thanks to the networks set up by Docker Compose. The front end now has access to the backend APIs.

What’s Next?

I hope the tutorial was helpful in you getting started with Docker Compose. To further your knowledge of Docker containers, learn how to manage volumes and scale up your application.


Also published here.