- September 22, 2017
- 3 min read
Configuration As Code With Docker and Spring Boot
What is Configuration as code?
Configuration as code is a DevOps practice that promotes storing of application configuration as code within source code repository. Few key benefits that this brings is that
- Versioning of application configuration
- By storing the application configuration in source code repository such as Git allows us to see what configuration changes were made over a period of time and who made those changes
- By using branches you can isolate changes that are under development without affecting the production application
- Traceability
- Versioned and managed properly, can provide tracking of what version of configuration is deployed in various environments
- Make configuration changes without requiring to re-deploy application
- Operators would love you for this for ex. Operators can throttle logging level up in configuration settings file to troubleshoot a production issue without having to redeploy the application.
Implementation
Now that we understand what configuration as code is and what benefits it brings let's take a look at how we would implement this with docker and spring boot. Spring boot provides support for keeping configuration settings in "yml" files instead of using a properties files, by default spring boot looks for these "yml" files under classpath but you can specify an explicit location by setting "spring.config.location" property via command line during application startup.
For the purpose of this article we have stored all default configurations for this demo application application.yml file and environment specific settings are stored in application-{environment label}.yml file as shown in screen capture below
Since we are running the spring boot app in docker, we can use an "entrypoint.sh" bash script to pull default configuration and environment specific configuration files from "git" repository onto directory named "configs" as shown below using wget command.
echo "Downloading configuration files from git repository"
wget $GIT_REPO/$LABEL/$REL_PATH/$APP_NAME.yml
wget $GIT_REPO/$LABEL/$REL_PATH/$APP_NAME-$PROFILE.yml
echo "copying yml files to configs directory"
cp $APP_NAME.yml ./configs/$APP_NAME.yml
cp $APP_NAME-$PROFILE.yml ./configs/$APP_NAME-$PROFILE.ymlAs you can see from the above snippet
- "GIT_REPO" environment variable is used to pass the git repository URL where the configuration files are stored.
- "LABEL" environment variable maps to the branch, in development/test/staging phases you might use "MASTER", when you release it to production you'll want to create a branch and use that branch label. This allows us to isolate changes that are under development from impacting the production application.
- "REL_PATH" environment variable is used to point to the location of configuration files in repo relative to the repository path.
- "APP_NAME" environment variable maps to file name, in the demo app I'm keeping default name "application"
- "PROFILE" environment variable maps to name of environment which the application is running. Spring boot will merge the default settings and environment specific settings and provide it to your application.
(Note: If your git repository requires authentication you can use ssh or HTTPS protocol with username and password to authenticate with the git repository. Docker container can obtain the credentials required to connect to git repository during startup.)
Once the configuration files are downloaded from repository onto "configs" directory in the container we specify this location via application startup using the "spring.config.location" property as shown in below snippet
exec java $JAVA_OPTS -jar /app.jar --spring.config.location="./configs/$APP_NAME.yml, ./configs/$APP_NAME-$PROFILE.yml"Running the demo application
Let's now run this demo application with staging settings as shown in command below
docker run -d -p 80:8080 -e PROFILE=staging -e GIT_REPO="https://raw.githubusercontent.com/rprakashg/blog-demos" \
-e LABEL=master -e REL_PATH="externalize-config-demo/src/main/resources" \
-e APP_NAME="application" rprakashg/externalize-config-demoDemo application simply displays the configuration information and you can see from the screen capture below that application has picked up default settings as well as staging environment specific settings.
Let's run the same demo application now with production settings as shown in snippet below.
docker run -d -p 80:8080 -e PROFILE=production -e GIT_REPO="https://raw.githubusercontent.com/rprakashg/blog-demos" \
-e LABEL=master -e REL_PATH="externalize-config-demo/src/main/resources" \
-e APP_NAME="application" rprakashg/externalize-config-demoAs you can see from the screen show below that the application now picks up default as well as production specific settings.
Source Code
All the code for the demo application is available at this github repository
Conclusion
Configuration as code is a good practice that all development teams practicing devops should follow. Many of the benefits gained from implementing configuration as code can help increase velocity and deliver new features to your customers in production faster and help operators run and manage application in production efficiently.
Related Posts
RAM GOPINATHAN
August 12, 2026
Building Kubernetes-Style APIs: A Practical Walkthrough
Kubernetes real innovation is the declarative, self-healing API pattern. This post builds that pattern from scratch: an OpenAPI-first server, a Postgres-backed store instead of etcd, and a clean service/store split that keeps business logic out of the database
RAM GOPINATHAN
February 28, 2026
Automating post install configurations with cloud-init for Red Hat Enterprise Linux deployments on baremetal environments
Stop configuring servers by hand. Here's how cloud-init brings cloud-level automation to your physical infrastructure.
RAM GOPINATHAN
January 22, 2026
PODMAN TIPS: Implementing init container pattern for containers running on PODMAN
If you’ve worked with Kubernetes, you’re probably familiar with init containers—containers that run before the main application and are typically used for setup or initialization tasks. In this post,…