Microservices Context-based Configuration

DZone 's Guide to

Microservices Context-based Configuration

Microservices are on the rise, largely due to Docker containers and cloud resource schedulers. Let's look at deployment challenges and configuration of microservices.

· Integration Zone ·
Free Resource

Deployment Challenges

Microservices have become very popular partly due to the introduction of Docker containers and cloud resource schedulers such as Mesos. With all the advantages of modularity and distribution that they bring, microservices migrate considerable complexity from development to deployment:

  • An SSO is expected for uniform security access to services and for transferring the security context in service-to-service calls.

  • Services need to be packed into Docker images. Deployment instructions are essential to launch the composite application through a cloud resource scheduler.

  • Persistent state through disk volumes needs to be provisioned and services have to be launched physically close to their volumes and migrated along with the volumes.

  • Client-side or server-side service discovery is needed. Server-side discovery such as a dynamic DNS service (e.g. Mesos-DNS) can be used to map service instances to their symbolic name.

  • Centralized and dynamic configuration is required to avoid hard-coding sensitive data into Docker images and provide a context to the composite application that depends on the deployment profile.

Central and Dynamic Configuration

We will attempt to tackle the last concern, the centralized and dynamic configuration. We will employ Zookeeper and confd to provide context-based and deployment-time configuration to Spring Boot – based microservices.

confd Templates

A typical Spring Boot application is configured through its application.properties located in the working directory or the classpath. E.g.


# HTTP service
# Zookeeper

This can be converted to a confd template where the base path of configuration keys depends on the activated profile. The profile name is pulled from an environment variable which renders the template friendly to Docker image parameterization:


# {{$base:= print "/profiles/" (getenv "PROFILE")}}

# HTTP service
service.instances={{getv (print $base "/http/instances")}}
# Zookeeper
zookeeper.connection.timeout={{getv (print $base "/http/zk.connection.timeout")}}

The configuration template is accompanied by a template resource config:


src = "application.properties.tmpl"
dest = "/opt/service/application.properties"
keys = [

Docker Image

The Dockerfile installs confd and pulls the configuration templates and the Spring Boot jar into the image:

FROM java:8

ENV APP_HOME /opt/service
ENV APP_DATA = /var/lib/service

RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/*

# Create user & group
RUN /usr/sbin/groupadd -g 1000 srv 
    && /usr/sbin/useradd -M -d /opt/service -g srv -s /sbin/nologin -u 1000 srv

# Add confd
RUN wget "https://github.com/kelseyhightower/confd/releases/download/v0.10.0/confd-0.10.0-linux-amd64" -O /usr/bin/confd 
    && chmod +x /usr/bin/confd && mkdir -p /etc/confd/conf.d 
    && mkdir -p /etc/confd/templates

ADD *.toml /etc/confd/conf.d/
ADD *.tmpl /etc/confd/templates/

ADD start.sh /
RUN chmod +x /start.sh

# Create directories
ADD app.jar $APP_HOME/
RUN chown -R srv:srv $APP_HOME $APP_DATA

USER srv
CMD /start.sh


This can also be broken into a base image with confd and a service-specific image.

The start.sh script will accept a Zookeeper URL and pass it to confd which runs once to create the final application.properties before launching the executable JAR:

When the Docker instance is created, we pass 2 environment variables ZK=zookeeper_ip:2181 and PROFILE=test:


docker create -t -i \
    -p 8080:8080 \
    --name service \
    -e "ZK=$1" \
    -e "PROFILE=$2" \

All that is left is to setup the actual values in Zookeeper for a ‘test’ profile:

[zk: localhost:2181(CONNECTED) 1] create /profiles ""
[zk: localhost:2181(CONNECTED) 2] create /profiles/test ""
[zk: localhost:2181(CONNECTED) 3] create /profiles/test/http ""
[zk: localhost:2181(CONNECTED) 4] create /profiles/test/instances "4"
[zk: localhost:2181(CONNECTED) 5] create /profiles/test/zk.connection.timeout "10000"

Any of the other backend storage supported by confd, such as etcd and consul, could have been used as well. In addition confd can be deployed as a daemon that reacts to configuration updates, regenerates the configuration file and optionally restarts the Spring Boot process.

The above approach allows decoupling the Docker image from context-specific deployments and it is compatible with multi-container deployment tools such as docker-compose and distributed deployment platforms such as Kubernetes and Mesos.

configuration management ,docker ,ei ,enterprise integration ,integration ,microservices

Published at DZone with permission of John Georgiadis . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}