Spring Profiles – why you’ll love them
In the good old days, when you were writing your first few lines of code (and probably used PHP) you probably hardcoded any configuration strings right in to the code.
After you wrote your first working version you might wanted to deploy that ugly bastard onto some server, but you had to change any config lines by hand. It did didn’t matter because it was only you, your local dev environment and a server. But then you might have to deal with a second server for QA, now overtime you deployed your application you had to think about “Did I change that config line correctly?”.
So where are we today? Most us have local dev, dev server, test, preprod and prod servers, on top of that you might already dockerized your application. I recently came across a project (Java + Spring) with multiple environments and the team was still changing config parameters by hand, all I said was “Why the hell are you guys not using Profiles?” – apparently this still is a unknown concept to some Spring devs, even though it’s easy, especially with Spring Boot.
So here’s a quick-start guide.
Local, Dev, Test,…
Spring has built-in support for profiles, with Spring Boot the configuration is super easy.
Let’s say you have different database users on every environment (if not, put your shame hat on). For example you’re using Postgres, your application.properties might look something like this:
spring.datasource.url = jdbc:postgresql://localhost:5432/backend
spring.datasource.username = user
spring.datasource.password = password
To separate your environment specific configs, just create a one properties file per environment needed and name the like application-profilename.properties
Put all shared configuration into application.properties , you can see this as your base config. Spring loads this file first, the provided profile properties next, whereas all parameters in the profile specific properties override existing ones in the base properties.
Now all you have to do is provide the profile name when you start the application, in this form
--spring.profiles.active=profilename , you can even specify multiple profiles, comma separated.
In eclipse you have to configure this in your runtime configuration:
Here’s the command line version:
Now when you fire up your application, Spring tells you which profiles it will load:
If you’re running your application in a docker container, the Dockerfile will look something like this:
ADD backend-0.1.0.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar --spring.profiles.active=profilename" ]
Spring actually comes with a lot of other ways to provide the properties, if you mix these you have consider the sequence in which they are loaded and therefore might get overwritten.
See the Spring documentation for more.