Wednesday, January 04, 2017

Linking Containers together using --link and Docker Compose

Right now I am working on a project where :
- there is a need for the tomcat instance to connect to an Oracle instance .
-  Both of these run in docker containers
-  I consider the Oracle instance to be a shared docker service , meaning it will be used by other services than the tomcat instance and that I do not want to tear it down as regularly as the tomcat docker instance

I would first need to build an image of my webapp with tomcat6 using a command similar below :

docker build -t tomcat6-atlas .


Then typically i use the following commands to run my docker image for tomcat:

docker run -it --rm --link atlas_oracle12 --name tomcat6-atlas-server -p 8888:8080   tomcat6-atlas

This tells my docker that I want to :

  1.  run an image of tomcat6-atlas as a container 
  2. the alias name of the container should be tomcat6-atlas-server using the --name flag
  3. the port 8080 on the container should be mapped to 8888 on the host using -p flag
  4. and that i should link my atlas_oracle12 container which is already started ( check this blog entry )  to this tomcat6-atlas-server container that am firing using the --link flag . 
The --link flag is important because using this , I can specify for exampled the JDBC connection from my app in the  tomcat6-atlas-server container to point to the atlas_oracle12 container using the alias name directly instead of having to use some ip addresses ( which may change if I restart the oracle container ) .

You could actualy ping the atlas_oracle12 container from the tomcat6-atlas container just by doing ping atlas_oracle12  , you dont need to therefore know the ip address of atlas_oracle12 as long as you name what is the alias name of the container .

Docker Compose 

Now typically the above is great if you have a small project but assume that the tomcat6-atlas container had numerous dependencies with other containers then it the command quickly becomes quite volumetric and possibly error prone.

Here comes Docker Compose which simplifies the build and the run of the container using one yml /yaml file as shown below:


version: '2'
services:
    atlas_tomcat6:
      build: .
      build:
        context: .
        dockerfile: Dockerfile
      image: tomcat6-atlas:latest
      
      network_mode: bridge

      external_links:
        - atlas_oracle12
   
      ports:
        - 8888:8080
      privileged: true
      
This is typically written in a docker-compose.yml file and you need to also install Docker Compose

Important things is that :
  1. It specifies the name of the project as atlas_tomcat6
  2. It assumes that in the same location as the docker-compose.yml file there is a Dockerfile to perform the build
  3. It knows thats the name and tag of the image is 'tomcat6-atlas' and 'latest' respectively
  4. With the network_mode:bridge value it understands that instead of creating a seperate network for the docker compose triggered instance of the container that it needs to use the default network of the host bridge , that is it will be able to connect to atlas_oracle12 ( container which was not started by docker compose )
  5. Containers on which atlas_tomcat6 has a dependency on but triggered seperately are defined with external-links tag e.g atlas_oracle12
  6. ports tag specifies the port mappings
I can build an image for tomcat6-atlas using the command :

docker-compose build


Now all you need to do is to fire up docker-compose using :

docker-compose up

Note that if the previous build command was not executed as part of the up command the image would first be built and then started.

If you want to run this in the bakground then you an use the -d flag :

docker-compose up  -d

To shut down your containers just use :

docker-compose down 

No comments: