4. Docker Compose

4.1. Install docker-compose

We can use docker-compose to bring up a set of containers together. You will have to install docker-compose separately. On Linux, the following commands should install this CLI and check to see if it installed correctly.

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

docker-compose --version

4.2. docker-compose.yml

After you have installed docker-compose successfully, you need to create a docker-compose.yml file. The full specification of the different versions of the compose file is available. We create an example docker-compose.yml file as follows.

 1version: "3.7"
 2services:
 3  db:
 4    image: db-app:local
 5    container_name: db
 6    ports:
 7      - "3306:3306"
 8    volumes:
 9      - type: bind
10        source: ./mysql/docker-entrypoint-initdb.d
11        target: /docker-entrypoint-initdb.d
12        consistency: consistent
13    environment:
14      MYSQL_ROOT_PASSWORD: "oneoffcoder"
15    healthcheck:
16      test: mysqladmin ping -h localhost -p$$MYSQL_ROOT_PASSWORD && test '0' -eq $$(ps aux | awk '{print $$11}' | grep -c -e '^mysql$$')
17  flask:
18    image: rest-app:local
19    container_name: rest
20    ports:
21      - "5000:5000"
22    healthcheck:
23      test: ["CMD", "curl", "-f", "http://localhost:5000"]
24      interval: 60s
25      timeout: 10s
26      retries: 3
27      start_period: 40s
28    depends_on:
29      - db
30  ng:
31    image: ui-app:local
32    container_name: ui
33    ports:
34      - "80:80"
35    healthcheck:
36      test: ["CMD", "curl", "-f", "http://localhost:80"]
37      interval: 60s
38      timeout: 10s
39      retries: 3
40      start_period: 40s
41    depends_on:
42      - flask
43      - db

The YAML file is self-explanatory, for the most part.

  • We create three services: db, flask and ng.

  • Each service has a specified container image: db-app:local, rest-app:local and ui-app:local.

  • Note that we mount volumes and set environment variables where needed.

  • Lastly, we also specify healthchecks to make sure the services are running; when they fail, an attempt will be made to bring them back up.

4.3. Dockerfiles

4.3.1. MySQL

1FROM mysql:5

4.3.2. Flask

1FROM python:3
2
3WORKDIR /rest-app
4COPY ./rest-app .
5RUN pip install --no-cache-dir requests flask flask-cors mysql-connector-python SQLAlchemy
6
7CMD [ "python", "./app.py" ]

4.3.3. Angular

 1FROM node:lts as NodeBuilder
 2WORKDIR /tmp/ui-app
 3COPY ./ui-app .
 4RUN npm install -g @angular/cli@8.3.19
 5RUN npm install
 6RUN ng build
 7
 8FROM nginx:alpine 
 9COPY --from=NodeBuilder /tmp/ui-app/dist/ui-app /usr/share/nginx/html
10EXPOSE 80