DEV Community

Cover image for Docker compose
Z. QIU
Z. QIU

Posted on

Docker compose

Context

We usually need to run multiple docker containers when we deploy a web-app/website back-end project. These containers may also have inter-dependencies between each other, making it a really tedious work for me. I used to configure and bring up these containers manually by using a series of bash files. To do so, I need to remember the order of containers by heart, remember their launch file locations, and type manually multiple command lines in terminal. Fortunately there is the super tool Docker Compose who saves my ass.

Introduction

It's a tool that defines a list of containers to run with their configs and operations. In a sense, it is a little similar to how Dockefile works for defining a container.

As far as I understand, Dockerfile defines a list of instructions for bringing up a container, while compose defines a list for bringing up a containers group.

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. Compose works in all environments: production, staging, development, testing, as well as CI workflows.

Generally we need three steps for deploying with Compose:

  1. Define a Dockerfile or several Dockerfiles for one or several services of the project.

  2. Define all the services of the project in docker-compose.yml so they shall be run together in an isolated environment.

  3. Run docker-compose up and Compose starts and runs the entire app.

Installation

Installation of Docker Compose is quite simple. One can see (this page)[https://docs.docker.com/compose/install/] the official instructions for all the platforms. For Linux, I use the following cmd lines for installing it:

$ sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
Enter fullscreen mode Exit fullscreen mode

Try an example

I tried the simple example presented in the official doc.

In my flask_app folder, I firstly added one docker-compose.yml file which defined the following content:

version: "3.8"
services:
  web:
    build: .
    ports:
      - "8666:5000"
  redis:
    image: "redis:alpine"
Enter fullscreen mode Exit fullscreen mode

Clear as it shows, there are two services that shall be started up
: web and redis. And web service requires a port mapping as 8666:5000 and it's build file is located in current folder.

Now I defined a simple flask app which is a Python file app.py and fill in the following code :

import time
import redis
from flask import Flask

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

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

Enter fullscreen mode Exit fullscreen mode

To run this app, I need a Python-env service which can execute Python script and install dependency modules flask and redis. Thus we define a Dockerfile and a requirement.txt in flask_app folder.

File Dockerfile content:

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
Enter fullscreen mode Exit fullscreen mode

File requirement.txt contains:

flask
redis
Enter fullscreen mode Exit fullscreen mode

Till now, I have all the files for starting this web app. To summarize, web service is a python app which will be built from Dockerfile and binds container's 5000 port to host machine's 8666 port; redis is a standard Redis container started from a pulled official image with default port setting.

Now launch it (I have already installed docker-compose beforehand for my Huawei Cloud server):

sudo docker-compose up
Enter fullscreen mode Exit fullscreen mode

After some printed information about downloading and preparing, I see the following info regarding launching of the services:
Alt Text

And docker ps gives two more containers:
Alt Text

One can notice that the container name is formated as {folderName}_{serviceName}_1.

Now test it. In my browser, I type my_serverIp:8666 and it shows the page shown below. Each time I refresh it, the counter increases by one.
Alt Text

Reference:
https://docs.docker.com/compose/

Top comments (0)