Thursday April 2, 2015 - tags:    node.js, docker, microservice

Orchestrating multiple containers with compose


This is the fourth in a series of posts where I explore how to setup a dockerised micro-service node.js architecture. In this chapter we will learn how to use docker-compose previously called fig, an orchestration tool that allows you to define in a single file the various docker services in your application so they can run together in an isolated environment.

The source code for these posts can be found here: dockerised-micro-service-node-js-architecture

The introduction and future posts to this series can be found here:

In this post

Installing compose

Lets install compose, run the following commands

$curl -L`uname -s`-`uname -m` > /usr/local/bin/docker-compose

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

Run this command to make sure you have installed compose correctly.

$ docker-compose --version

Creating a compose file

Lets create a docker-compose file for our notifications service created in a previous pose and a dockerised mongodb instance, indentation is important in a compose file so please make sure its correct.

The notifications container, defines a build step, this uses the Dockerfile located ./notifications. We also use links to link to db container. We expose ports 3000:3000, and mount a volume at ./notifications:/src. The environment section allows us to define environment variables, here we add the NODE_ENV and set to development.

The db container defines an image, which we will use to build the image dockerfile/mongodb:latest. We also expose the mongodb ports as 27017:27017.

  build: ./notifications
   - db
    - "3000:3000"
   - ./notifications:/src
   NODE_ENV: development
  image: dockerfile/mongodb:latest
   - "27017:27017"

Build compose

Lets now build the application, this command also allows you to rebuild the application when changes are made to source or the dockerfile. This build step should create a notifications container named nodedockermicroservice_notifications_1 and a mongodb container called nodedockermicroservice_db_1.

$ docker-compose build

Working with compose

We are now in a position where we can start our application from a single command, and here it is.

docker-compose up will build, create or recreate, start and attach containers for a service, it will also start any linked services; this can also be run with the -d switch to run as a background process. If there are existing running containers for a service, docker-compose up will stop and recreate them; running docker-compose up with the --no-recreate switch will avoid stopping and recreating these containers.

Build and start compose
$ docker-compose up
$ docker-compose up -d
$ docker-compose up --no-recreate
Run commands against compose containers

We can run commands against the containers in our compose setup, for example the below simply outputs the contents of the working directory.

$ docker-compose run --no-deps notifications ls
$ docker-compose run --no-deps db ls

These commands will start in a new container with the same config as a normal container for that service, the --no-deps switch ensures linked containers are not started for these commands.

Compose environment variables

The following commands allow us to view compose environment variables.

$ docker-compose run notifications env
Run container interactively

This command is useful for debugging applications from the command line, as we can bash into our application and examine how compose has set this up.

$ docker-compose run notifications bash
See what compose containers are running

If you would like to view the containers running after running docker-compose up.

$ docker-compose ps

You should get a response, similar to.

       Name             Command     State                  Ports
src_db_1              mongod        Up>27017/tcp, 28017/tcp  
src_notifications_1   node app.js   Up>3000/tcp  
Stop running containers

This command allows us to stop all containers started by compose.

$ docker-compose stop
Start existing containers

This command simply restarts all stopped containers.

$ docker-compose start
Remove stopped containers

We can also remove stopped containers with the following.

$ docker-compose rm