Spring Boot lets you externalize configurations for our application. Lets take a simple application which connects to database and perform some operations on it. Standard configuration for this kind of app would be the database related details. Below is one sample properties
file
spring.datasource.url=${JDBC_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
Like this we might have more properties specific to our application also which we want to have it as dynamic configurations that can be passed when application startup. In order to have these have different across different environments like dev,staging,production. Spring boot provides us with option to have environment specific files with different values for different environments.
Below are few common practices developers follow which has its own pros and cons
- Commit secrets in these files as part of the code base
- Commit only local configuration in the code base and as part of deployment pipeline copy environment specific files from different repository and build the package
If we are having separate profile files then we might need to have separate start-up scripts for each to ensure right profile details are passed. If we are copying files at the time of the build for any change in secrets or configurations we might need to build the package again to take effect.
According to 12factor apps its good practice to store configurations in environments.
How can we achieve this?
- We can avoid multiple property files and have only one file as below
spring.datasource.url=${JDBC_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
The above helps in multiple ways
- No need to rebuild the package again if there is any change in configuration.
- One common properties file versioned as part of code base.
- Build pipelines would be generic. Same builds can be used across all environments
When running as containers
If we are running our application as containers we need to pass the environment variables while starting the application. This can be taken care by a deployment pipeline.If there is a change in value just a restart of the container is enough
When running as fat jars
If we are running our application as normal jars then best practice would be to set the environment variables as part of the host machine and start the application.
What about local development/tests
For tests I would recommend to have dedicated properties file. For local development we can do it two ways.
- Have one
.env
file in local andsource
them before starting the application - We can give default values to properties if not present in environment as
spring.datasource.username=${DB_USERNAME:username}
The key thing to note here is the deployment process. I will cover a detailed blog on how the deployment pipeline can be done for such a setup of spring boot application.
Top comments (0)