Docker Compose

for

Developing Microservices

Can Kutlu Kınay
Software Engineer @ unu GmbH

cakuki

ckk.im

  • $> docker run --name db -p 27017:27017 -d mongo:3.6.0
  • $> docker run --name api -d \
  •                           --link db \
  •                           -p 3000:3000 \
  •                           api:latest npm start

 

 

 

 

  • $> for service in services/*; do
  •           docker run --name ${service}-service
  •                                --link db \
  •                                 --env CUSTOM_SETTING=? \
  •                                 --port ?? ...

Microservices

Enter
Docker
Compose

Defines whole stack

Single command

In isolated networks

How does it work?

Define images

Define stack

./api/Dockerfile

docker-compose.yml

Up!

FROM node:9.2

COPY package*.json ./
RUN npm install

COPY index.js

CMD ["npm", "start"]
version: '3'
services:
 web:
  image: nginx:1.13.7
  volumes:
   - ./web:/usr/share/nginx/html
  ports:
   - "8080:80"
 api:
  build: ./api/
  depends_on:
   - db
  ports:
   - "3000:3000"
 db:
  image: mongo:3.6.0
$> docker-compose up

Creating network "example_default"
Pulling db (mongo:3.6.0)...
3.6.0: Pulling from library/mongo
Building api
Step 1/5 : FROM node:9.2
9.2: Pulling from library/node
Step 2/5 : COPY package.json ./
Step 3/5 : RUN npm install
Step 4/5 : COPY index.js ./
Step 5/5 : CMD ["npm", "start"]
Successfully built
Successfully tagged example_api:latest
Creating example_db_1 ...
Creating example_db_1 ... done
Creating example_api_1 ...
Creating example_api_1 ... done
Creating example_web_1 ...
Creating example_web_1 ... done

api_1 | Example app listening on port 3000!

Basic Stack

version: '3'

services:
#---------------------------------
  web:
    image: nginx:1.13.7
    volumes:
     - ./web:/usr/share/nginx/html
    ports:
     - "8080:80"
#---------------------------------
  api:
    image: api:latest
    build: ./api/
    depends_on:
     - db
    ports:
     - "3000:3000"
#---------------------------------
  db:
    image: mongo:3.6.0

foobar/docker-compose.yml

foobar_web_1
(nginx:1.13.7)

foobar_api_1
(api:latest)

foobar_db_1
(mongo:3.6.0)

foobar_network

web

api

What about more services?

services
├── cart
│   ├── Dockerfile
│   ├── index.js
│   └── package.json
├── checkout
│   ├── Dockerfile
│   ├── index.js
│   └── package.json
├── payment
│   ├── Dockerfile
│   ├── index.js
│   └── package.json
├── stock
│   ├── Dockerfile
│   ├── index.js
│   └── package.json
└── web
    └── index.html
version: '3.0'
services:
  cart-service:
    build: services/cart
    depends_on:
    - db
    ports:
    - 3000:3000/tcp
  checkout-service:
    build: services/checkout
    ...
  payment-service:
    build: services/payment
    ...
  stock-service:
    build: services/stock
    ...
  web:
    image: nginx:1.13.7
    ports:
    - 8080:80/tcp
    volumes:
    - ./services/web:/usr/share/nginx/html:rw
  db:
    image: mongo:3.6.0

Even more services?

Growing
docker-compose.yml

version: '2.1'
web:
  extends:
    file: common-services.yml
    service: webapp
  environment:
    - DEBUG=1
  cpu_shares: 5

important_web:
  extends: web
  cpu_shares: 10

Extending

$> docker-compose -f services/checkout/service.yml \
                  -f services/order/service.yml \
                  -f services/payment/service.yml \
                  ... \
                  up --detach

Or multiple YAML files

Multiple YAML files

$> docker-compose -f services/checkout/service.yml \
                  -f services/order/service.yml \
                  -f services/payment/service.yml \
                  ... \
                  up --detach

Template

for service in services; do;
    cat >"stack/${service}.yml" <<EOF

    version: '3'
    services:
      ${service}-service:
        build: services/${service}
        depends_on:
         - db

    EOF
done
├── services
│   ├── cart
│   ├── checkout
│   ├── payment
│   ├── stock
│   └── web
├── stack
│   ├── cart.yml
│   ├── checkout.yml
│   ├── db.yml
│   ├── payment.yml
│   ├── stock.yml
│   └── web.yml
└── docker-compose.yml

Wrapping it up (literally)

#!/bin/bash -e

CONFIG_FILES=(stack/*.yml)

docker-compose ${CONFIG_FILES[@]/#/-f} ${@}
├── services
│   ├── cart
│   ├── checkout
│   ├── payment
│   ├── stock
│   └── web
├── stack
│   ├── cart.yml
│   ├── checkout.yml
│   ├── db.yml
│   ├── payment.yml
│   ├── stock.yml
│   └── web.yml
└── wrapper

./wrapper script

Replace all docker-compose commands

./wrapper up --build --scale api=2
./wrapper down
./wrapper up
#!/bin/bash -e

docker-compose -f stack/checkout.yml \
               -f stack/order.yml \
               ... \
               ${@}

Thanks!

Questions?

Can Kutlu Kınay
Software Engineer @ unu GmbH

cakuki

ckk.im

Docker Compose for Developing Microservices

By Can Kutlu Kınay

Docker Compose for Developing Microservices

Short recap of Docker Compose with tips & tricks to use it on your microservices architecture development Prepared for lightning talk in DevOps Berlin meet up group on 13.12.2017.

  • 92