Spring-boot Docker example


Goal of this example

This example shows how to create a “microservice ecosystem” from multiple dockerized spring boot applications that see each other, but only one of them is accessible outside of docker. This is a common approach in a microservice architecture where the API Gateway is the only externally available service that proxies all other intertnal services. Inside the “ecosystem” the number or running instances can change dynamically. Such a dockerized ecosystem can be used for

  • Setting up a local test environment of a microservice project
  • Testing different cluster configurations
  • Testing cluster fail-over

We will build the following :

boot-docker
We will use a Zuul API Gateway and an Eureka service registry. Details of how they work will be explained in an another blog post, but what matters for this exercise is that they are regular spring boot applications. A very similar ecosystem could be build from any java application.

Technology Used

  • Spring boot 1.3.5.RELEASE
  • Docker
  • Docker Compose
  • Docker maven plugin
  • Zuul
  • Eureka

How to create a docker image from a spring boot application

Our first goal is to generate a Docker image from a Spring boot application using maven. This can be achieved by the Spotify docker maven plugin. It eliminates the need to create a Dockerfile, instead all important properties like the base image and entrypoint can be set in the pom.xml like this :


            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.4.10</version>
                <configuration>
                    <imageName>${project.artifactId}</imageName>
                    <baseImage>java:8</baseImage>
                    <entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
                    <!-- copy the service's jar file from target into the root directory of the image -->
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
                <executions>
                    <execution>
                        <id>build-image</id>
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

This does the following :

  • Sets the <baseImage> (equivalent to FROM in dockerfile) to java:8
  • Sets the <entryPoint> (equivalent to CMD in dockerfile) to the generated jar file.
  • Binds the plugin to the build goal, so it will be automatically executed when <pre>mvn install</pre> is executed

If the command was successfully executed then we should see the image listed when

 docker images 

is executed.

Link docker containers to see each other over the network

Once we have our docker images we want to start them up in a way they connect to each other over the network. The legacy way to do is to use the -link command, e.g.: like this :

 
## Starts up an eureka image, names it eureka-server and exposes port 8761 
docker run -p 8761:8761 --name eureka-server eureka-server 

## Starts up an echo-service image and makes the container named eureka-server accessible over the network by the eureka-server name 
docker run --name echo-service --link eureka-server echo-service 

Use docker-compose the start up multiple containers and set up a container network

Docker compose is a command line tool to start up multiple predefined containers. Container definitions are stored in a file named docker-compose.yml . The above example starts up three containers. The depends_on defines the startup order and how containers see the other. The file also defines the exposed ports of the services.

version: '2'
services:
  echo-service:
    image: echo-service
    depends_on:
     - eureka-server
  eureka-server:
    image: eureka-server
    ports:
     - "8761:8761"
  zuul-server:
    image: zuul-server
    depends_on:
     - eureka-server
    ports:
     - "9090:9090"

The above file defines that

  • Eureka will expose it’s 8761 port to the external network
  • Zuul server will expose it’s 9090 port to the external network
  • Echo-service will be only internally accessible

To start up the containers build all images then type

##use the -d option to start up in deamon mode

docker-compose up

docker compose could also build the images, but it would require a Dockerfile that we replaced with the Docker maven plugin. Once the services are up you can execute a few commands to validate the setup

##show running docker containers
docker ps

##List docker netwrks
docker network ls

Scaling

One fo the many benefits of docker-compose is that it allows easy scaling of the services. For example if we want two echo-service containers then simply call

<span class="pl-c">##starts a 2nd instance of echo-service</span> 
docker-compose scale echo-service=2

Resource utilization

Starting up three or more VMs would require a lot of time and resource. Docker containers share their resources with the host, therefore the overhead is very minimal. The startup time and memory footprint of a dockerized java application is almost identical to a regulat java application.

One comment

  1. Pingback: Spring Cloud Zuul example | Example Driven (Self) Development

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: