Z. QIU
Posted on November 30, 2020
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:
Define a Dockerfile or several Dockerfiles for one or several services of the project.
Define all the services of the project in docker-compose.yml so they shall be run together in an isolated environment.
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
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"
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)
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"]
File requirement.txt contains:
flask
redis
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
After some printed information about downloading and preparing, I see the following info regarding launching of the services:
And docker ps
gives two more containers:
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.
Reference:
https://docs.docker.com/compose/
Posted on November 30, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 4, 2020