DevOps

Docker basics: Docker compose

Docker Compose is a tool that allows you to run multi-container applications. With compose we can use yaml files to configure our application’ services and then using a single command create and start all of the configured services. I use this tool a lot when it comes to local development in a microservice environment. It is also lightweight and needs just a small effort. Instead of managing how to run each service while developing you can have the environment and services needed preconfigured and focus on the service that you currently develop.

With docker compose we can configure a network for our services, volumes, mount-points, environmental variables just about everything.
To showcase this we are going to solve a problem. Our goal would be to extract data from mongodb using grafana. Grafana does not have out of the box support for MongoDB therefore we will have to use a plugin.

First step we shall create our networks. Creating a network is not necessary since your services once started will join the default network. We shall make a showcase of using custom networks. We shall have a network for backend services and a network for frontend services. Apparently network configuration can get more advanced and specify custom network drivers or even configure static addresses.

1
2
3
4
5
6
7
8
version: '3.5'
 
networks:
  frontend:
    name: frontend-network
  backend:
    name: backend-network
    internal: true

The backend network is going to be internal therefore there won’t be any outbound connectivity to the containers attached to it.

Then we shall setup our mongodb instance.

01
02
03
04
05
06
07
08
09
10
11
12
13
version: '3.5'
 
services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
    volumes:
      - ${DB_PATH}:/data/db
    networks:
      - backend

As you see we specified a volume. Volumes can also be specified separately and attach them to a service.
Also we used environmental variables for the root account, you might as well have spotted that the password is going to be provided through environmental variables ie. MONGO_USER=root MONGO_PASSWORD=root docker-compose -f stack.yaml up. The same applies for the volume path too. You can have a more advanced configuration for volumes in your compose configuration and reference them from your service.

Our next goal is to setup the proxy server which shall be in the middle of our grafana and mongodb server. Since it needs a custom Dockerfile to create it, we shall do it through docker-compose. Compose has the capability to spin up a service by specifying the docker file.

So let’s start with the Dockerfile.

01
02
03
04
05
06
07
08
09
10
11
FROM node
 
WORKDIR /usr/src/mongografanaproxy
 
COPY . /usr/src/mongografanaproxy
 
EXPOSE 3333
 
RUN cd /usr/src/mongografanaproxy
RUN npm install
ENTRYPOINT ["npm","run","server"]

Then let’s add it to compose

01
02
03
04
05
06
07
08
09
10
version: '3.5'
 
services:
  mongo-proxy:
    build:
      context: .
      dockerfile: ProxyDockerfile
    restart: always
    networks:
      - backend

And the same shall be done to the Grafana image that we want to use. In stead of using a ready grafana image we shall create one with the plugin preinstalled.

1
2
3
4
5
FROM grafana/grafana
 
COPY . /var/lib/grafana/plugins/mongodb-grafana
 
EXPOSE 3000
01
02
03
04
05
06
07
08
09
10
11
12
13
version: '3.5'
 
services:
  grafana:
    build:
      context: .
      dockerfile: GrafanaDockerfile
    restart: always
    ports:
      - 3000:3000
    networks:
      - backend
      - frontend

Let’s wrap them all together

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
version: '3.5'
 
services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER}
      MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD}
    volumes:
      - ${DB_PATH}:/data/db
    networks:
      - backend
  mongo-proxy:
    build:
      context: .
      dockerfile: ProxyDockerfile
    restart: always
    networks:
      - backend
  grafana:
    build:
      context: .
      dockerfile: GrafanaDockerfile
    restart: always
    ports:
      - 3000:3000
    networks:
      - backend
      - frontend
networks:
  frontend:
    name: frontend-network
  backend:
    name: backend-network
    internal: true

So let’s run them all together.

1
2
docker-compose -f stack.yaml build
MONGO_USER=root MONGO_PASSWORD=root DB_PATH=~/grafana-mongo  docker-compose -f stack.yaml up

The above can be found on github.

You might as well find the Docker Images, Docker Containers and Docker registry posts useful.

Published on Web Code Geeks with permission by Emmanouil Gkatziouras, partner at our WCG program. See the original article here: Docker basics: Docker compose

Opinions expressed by Web Code Geeks contributors are their own.

Emmanouil Gkatziouras

He is a versatile software engineer with experience in a wide variety of applications/services.He is enthusiastic about new projects, embracing new technologies, and getting to know people in the field of software.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button