In my previous post I detailed how I Dockerised the MedRec app. In this post I will show how I added MongoDB and defined a stack using Docker-Compose.
Add MongoDB layer using Docker-Compose
According to the official docker documentation ;
“Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a Compose file to configure your application’s services. Then, using a single command, you create and start all the services from your configuration. ”
A single command to create and start all the services in a configuration sounded pretty good to me. I definitely was keen on exploring docker-compose.
Add a docker-compose.yml file
Having proved that my web application runs up, I now need to address the persistence layer. The above Dockerfile contains the steps to create the required runtime platform for my node app, and installs the node application and package dependences (as specified in the package.json) file by doing the npm install. However if I tried to do a GET or a PUT my app will fail as it won’t find a MongoDB inside my container. I therefore still need a MongoDB somewhere in my environment to hold my application data.
As I understand things I have essentially two options;
- Include the MongoDB installation and run command (would require a script) inside my Dockerfile which seems to violate the modern microservice based approach where ideally all the layers can independently scale.
- Use docker-compose to deal with a multi-container Docker application, such that my application and database tiers can run in separate containers but be aware of each other.
I decided to try out the docker-compose approach. In the root directory of my project I did the following;
I then edited the above file to contain the following;
In the above file there are two services defined ( web application service and the mongo database service) .
The links section points out that there is a dependency on the service detailed in the mongo section.
The image section shown under the mongo service, allows me to specify the docker image to pull from my registry of choice (in my case I am using Docker Hub).
For my purposes I chose to use an official mongo database image from the docker hub image repository.
The file also highlights that the container network ports 3000 and 27017 are mapped to ports 3000 and 27017 on the host (which in my case was my Ubuntu VM).
Note: If I wanted to use a different public or private docker repository I could just have easily referenced a different image and repository location using the following syntax;
Building and Running the Docker Image using Compose
I used the following command to build the image using the docker-compose utility and the configuration specified in my docker-compose.yml file;
To start the container I did the following;
Note: I experienced the following issue when executing the docker-compose up command.
The issue was that I had MongoDB installed locally and it was still running and a port conflict was the result.
To prove it I did the following;
netstat -a | grep 27017
Clearly the process using the 27017 port was my local MongoDB. My options were to either shut down my local MongoDB or change the port reference in my docker-compose.yml file.
I chose to shut down my locally running MongoDB so I could keep a standard port reference in my docker-compose.yml file. To shut down MongoDB I did;
Add occs-stack.yml file
OCCS provides a runtime environment for Docker images, think of this as Bring Your Own Container. It is not a Docker build environment. It supports some of the docker-compose functionality but not all. This presented me with a small issue when I wanted to deploy the image and tried to use my previously created docker-compose.yml file because it contains a “build” reference in it. For an OCCS deployment to succeed the image would have to exisit (already have been built) so that it could be pulled into the OCCS runtime environment. I decided to separate concerns of build and run and created an occs-stack.yml file based on docker-compose.yml. I had to make two changes to the occs-stack.yml file to get this to work.
My occs-stack.yml file contains the following information;
The areas of difference between docker-compose.yml and the occs-stack.yml files can be readily noticed.
- Under the services: web: there is now a link to a docker image on docker hub instead of the build . instruction that was in the docker-compose.yml file.
- Under the image : mongo there is a slight change to the volume mapping. I now reference /u01/data instead of /data>
This means that the datafiles for my mongo container will be written onto the volume associated with the OCCS worker node host. That is, the datafiles will be persisted outside of the container.
Check out the next episode in the series – Triggering a build of an image using Docker Hub and GitHub