Home Building and Running Services with Docker Compose
Post
Cancel

Building and Running Services with Docker Compose

Docker Compose

  • docker-compsoe is used for defining and running multi-container Docker applications.
  • docker-compose uses docker-compose.yaml file to configure application’s services, and after with a single command, you create and start all the services from your configuration.
  • docker-compose can be used in all environment, for example in production, staging, development, testing, as well as CI workflows.
  • Some of features are :
    • Start, stop, and rebuild services
    • View the status of running services
    • Stream the log output of running services
    • Run a one-off command on a service

Docker Compose Directive :

There are alot of configuration (key-value pairs and directives) in docker-compose file. The top Levels are :

1
2
3
4
Version
Services
Network
Volumes
  • Now lets look at the example of docker-compose.yml file
1
2
3
4
5
6
7
8
9
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
version: "3.8"
services:
    client:
        build:
            context: ./client
        ports:
            - "4200:4200"
        container_name: client
        depends_on:
            [api, webapi]

    api:
        build:
            context: ./nodeapi
        ports:
            - "5000:5000"
        container_name: api
        depends_on:
            - nginx
        depends_on:
            [emongo]

    webapi:
        build:
            context: ./javaapi
        ports:
            - "9000:9000"
        restart: always
        container_name: webapi
        depends_on:
            [emartdb]

    nginx:
        restart: always
        image: nginx:latest
        container_name: nginx
        volumes:
            - "./nginx/default.conf:/etc/nginx/conf.d/default.conf"
        ports:
            - "80:80"
        command: ['nginx-debug', '-g', 'daemon off;']
        depends_on:
            [client]

    emongo:
       image: mongo:4
       container_name: emongo
       environment:
         - MONGO_INITDB_DATABASE=epoc
       ports:
         - "27017:27017"

    emartdb:
      image: mysql:5.7
      container_name: emartdb
      ports:
         - "3306:3306"
      environment:
        - MYSQL_ROOT_PASSWORD=emartdbpass     
        - MYSQL_DATABASE=books

Another example :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: '3'
services:
  app:
    image: node:latest
    container_name: app_main
    restart: always
    command: sh -c "yarn install && yarn start"
    ports:
      - 8000:8000
    working_dir: /app
    volumes:
      - ./coderepo:/app
    environment:
      MYSQL_HOST: localhost
      MYSQL_USER: root
      MYSQL_PASSWORD: 
      MYSQL_DB: test
  mongo:
    image: mongo
    container_name: app_mongo
    restart: always
    ports:
      - 27017:27017
    volumes:
      - mongodb:/data/db
volumes:
  mongodb:

Now lets see the details about various options/configurations

  • version : Refers to the docker-compose version. The latest version is 3.8 (as of now).
1
version: "3.8"
  • services : Defines the services that we need to run
1
services: 
  • service_name : it is a custom name for one of your containers, for example app, mongo etc.
1
2
3
4
5
6
7
8
9
10
version: "3.8"
services: 
  service_one:
    service_declaration....
    ...
    ...
  service_two:
    service_declaration....
    ...
    ...
  • image : The image which we have to pull. Here we are using node:latest and mongo.
1
2
3
4
version: "3.8"
services: 
  service_one:
    image: node:latest
  • container_name : Name for each container.
1
2
3
4
5
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one

often the container name would be similer to the service name.

  • restart : starts/restarts a service container.
1
2
3
4
5
6
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one
    restart: always
  • port : Defines the custom port to run the container.
1
2
3
4
5
6
7
8
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one
    restart: always
    ports:
      - 8000:8000
  • working_dir : The current working directory for the service container.
1
2
3
4
5
6
7
8
9
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one
    restart: always
    ports:
      - 8000:8000
    working_dir: /app
  • environment : Defines the environment variables, such as DB credentials, and so on.
1
2
3
4
5
6
7
8
9
10
11
12
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one
    restart: always
    ports:
      - 8000:8000
    working_dir: /app
    environment:
      - MYSQL_ROOT_PASSWORD=emartdbpass     
      - MYSQL_DATABASE=books
  • command : Run the command at the container startup. Command provided here will overide the dockerfile command as well as docker image default command.
1
2
3
4
5
6
7
8
9
10
11
12
13
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one
    restart: always
    ports:
      - 8000:8000
    working_dir: /app
    environment:
      - MYSQL_ROOT_PASSWORD=emartdbpass     
      - MYSQL_DATABASE=books
    command: sh -c "yarn install && yarn start"
  • volumes : Used to mount a docker volume or a host file directory into docker container.

Mounting a host directory into docker container

1
2
3
4
5
6
7
8
9
10
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one
    restart: always
    ports:
      - 8000:8000
    volumes:
      - ./coderepo:/app

Mounting a docker volume into docker container

1
2
3
4
5
6
7
8
9
10
11
12
version: "3.8"
services: 
  service_one:
    image: node:latest
    container_name: service_one
    restart: always
    ports:
      - 8000:8000
    volumes:
      - ~/mongo:/data/db
volumes:
  mongodb:

Also at the last line you need to define the mongodb volume, if you are going to mount the volume.

  • build : Used to build a Docker image from a Dockerfile and then use that image to start a container.
    • context : specifies the build context, which is the directory where the build process is executed.
    • dockerfile : specifies the name of the Dockerfile to use for the build process.
1
2
3
4
5
6
7
version: '3.8'
services:
  my_service:
    build: 
      context: .
      dockerfile: Dockerfile
    image: my_image
  • depends_on : specify the order in which services are started. Specifically, it defines the dependencies between services.
1
2
3
4
5
6
7
8
9
services:
  web:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      - db
  db:
    image: postgres

Another example :

1
2
3
4
5
6
7
8
9
10
11
services:
  web:
    build: .
    ports:
      - "8000:8000"
    depends_on:
      [db, webapi]
  db:
    image: postgres
  webapi:
    image: mywebserver
  • networks : Used to define custom networks for your Docker containers. You can create custom networks using the networks keyword and then specify which networks each service should use using the networks tag in the service definition.
1
2
3
4
5
6
7
8
version: '3.8'
networks:
  my_network:
services:
  my_service:
    image: my_image
    networks:
      - my_network

At above example, we define a custom network named my_network using the networks keyword.

Docker Compose Commands

  • Build the docker images and containers
1
2
3
4
5
6
$ docker-compose build

* `docker-commpose` command : Builds and starts containers defined in a Compose file. Creates the containers and links them as specified in the file,  and then starts them in the foreground, so you can see their logs in the terminal. If a container doesn't exist, it will be built first.   

```bash   
$ docker-compose up  
  • Start the containers in background
1
$ docker-compose up -d  
  • Stop the containers
1
$ docker-compose down  
  • Start the aleady build/deployed containers
1
$ docker-compose start  

Above command starts containers that have already been created using docker-compose up, but are currently stopped. If a container has never been created, this command will do nothing.

  • List the running containers
1
$ docker-compose ps  
  • Stop the running containers
1
$ docker-compose stop  
  • Check the logs of running containers
1
$ docker-compose logs -f <container_name>
  • Receive real time events from containers
1
$ docker-compose events
  • Run bash shell onto containers
1
$ docker-compose exec db bash

Detailed article on docker-compose

This post is licensed under CC BY 4.0 by the author.