Using env variable in Spring Boot's application.properties

spring boot set environment variable programmatically
how to read system environment variable in spring application context
spring boot pass environment variables command line
spring boot not reading environment variables
spring boot environment variables docker
spring boot set environment variable runtime
spring value(#(environment variable))
spring boot dotenv

We are working on a Spring Boot web app and the database we are using is MySql;

  • the setup we have is we first test it locally (means we need to instal MySql on our PC);

  • then we push to Bitbucket;

  • Jenkins automatically detects the new push to Bitbucket and does a build on it (for Jenkins mvn build to pass we also need to install MySql on the virtual machines that is running Jenkins).

  • if Jenkins build passes we push the code to our application on OpenShift (using the Openshift deployment plugin on Jenkins).

The problem we have as you may have already figured it out is that:

  • in application.properties we can not hard code the MySql info. Since our project will be running in 3 different places (local, Jenkins, and OpenShift) we need to make the datasource field dynamic in application.properties (we know there are different way's of doing it but we are working on this solution for now).

    spring.datasource.url = 
    spring.datasource.username = 
    spring.datasource.password = 
    

The solution we came up with is we create system environment variables locally and in the Jenkins vm (naming them the same way OpenShift names them) and assigning them the right values respectively:

export OPENSHIFT_MYSQL_DB_HOST="jdbc:mysql://localhost"
export OPENSHIFT_MYSQL_DB_PORT="3306"
export OPENSHIFT_MYSQL_DB_USERNAME="root"
export OPENSHIFT_MYSQL_DB_PASSWORD="123asd"

We have done this and it works. We have also checked with Map<String, String> env = System.getenv(); that the environment variables can be made into java variables as such:

String password = env.get("OPENSHIFT_MYSQL_DB_PASSWORD");   
String userName = env.get("OPENSHIFT_MYSQL_DB_USERNAME");   
String sqlURL = env.get("OPENSHIFT_MYSQL_DB_HOST"); 
String sqlPort = env.get("OPENSHIFT_MYSQL_DB_PORT");

Now the only thing left is we need to use these java variables in our application.properties and that is what we are having trouble with.

In which folder, and how, do we need to assign the password, userName, sqlURL, and sqlPort variables for application.properties to be able to see them and how do we include them in application.properties?

We have tried many things one of them being:

spring.datasource.url = ${sqlURL}:${sqlPort}/"nameofDB"
spring.datasource.username = ${userName}
spring.datasource.password = ${password}

No luck so far. We are probably not putting these env variables in the right class/folder or are using them incorrectly in application.properties.

Your help is highly appreciated!!

Thanks!

You don't need to use java variables. To include system env variables add the following to your application.properties file:

spring.datasource.url = ${OPENSHIFT_MYSQL_DB_HOST}:${OPENSHIFT_MYSQL_DB_PORT}/"nameofDB"
spring.datasource.username = ${OPENSHIFT_MYSQL_DB_USERNAME}
spring.datasource.password = ${OPENSHIFT_MYSQL_DB_PASSWORD}

But the way suggested by @Stefan Isele is more preferable, because in this case you have to declare just one env variable: spring.profiles.active. Spring will read the appropriate property file automatically by application-{profile-name}.properties template.

Using env variable in Spring Boot's application.properties, We are working on a Spring Boot web app and the database we are using is MySql;. the setup we have is we first test it locally (means we need to instal MySql on  At application startup, Spring Boot will look for an environment variable called SPRING_APPLICATION_JSON. It can be used to provide a set of application properties using inline JSON. It can be used to provide a set of application properties using inline JSON.

The easiest way to have different configurations for different environments is to use spring profiles. See externalised configuration.

This gives you a lot of flexibility. I am using it in my projects and it is extremely helpful. In your case you would have 3 profiles: 'local', 'jenkins', and 'openshift'

You then have 3 profile specific property files: application-local.properties, application-jenkins.properties, and application-openshift.properties

There you can set the properties for the regarding environment. When you run the app you have to specify the profile to activate like this: -Dspring.profiles.active=jenkins

Edit

According to the spring doc you can set the system environment variable SPRING_PROFILES_ACTIVE to activate profiles and don't need to pass it as a parameter.

is there any way to pass active profile option for web app at run time ?

No. Spring determines the active profiles as one of the first steps, when building the application context. The active profiles are then used to decide which property files are read and which beans are instantiated. Once the application is started this cannot be changed.

24. Externalized Configuration, Spring Boot allows you to externalize your configuration so you can work with the same You can use properties files, YAML files, environment variables and into your beans using the @Value annotation, accessed via Spring's Environment  Using env variables with Spring Boot This is an example application which demonstrates how to configure a Spring Boot app via environment variables. It expects to receive three properties. Default values are provided in the app.

This is in response to a number of comments as my reputation isn't high enough to comment directly.

You can specify the profile at runtime as long as the application context has not yet been loaded.

// Previous answers incorrectly used "spring.active.profiles" instead of
// "spring.profiles.active" (as noted in the comments).
// Use AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME to avoid this mistake.

System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, environment);
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/META-INF/spring/applicationContext.xml");

Spring Boot Environment, It can be use to get profiles and properties of the application environment. $ echo %JAVA_HOME% C:\Users\Jano\AppData\Local\Programs\Java\  According to the spring doc you just have to set the OS environment variable SPRING_PROFILES_ACTIVE to activate profiles and don’t pass it as a parameter. is there any way to pass active profile option for web app at run time ? No. Spring determines the active profiles as one of the first steps, when building the application context.

Here is a snippet code through a chain of environments properties files are being loaded for different environments.

Properties file under your application resources ( src/main/resources ):-

 1. application.properties
 2. application-dev.properties
 3. application-uat.properties
 4. application-prod.properties

Ideally, application.properties contains all common properties which are accessible for all environments and environment related properties only works on specifies environment. therefore the order of loading these properties files will be in such way -

 application.properties -> application.{spring.profiles.active}.properties.

Code snippet here :-

    import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;

    public class PropertiesUtils {

        public static final String SPRING_PROFILES_ACTIVE = "spring.profiles.active";

        public static void initProperties() {
            String activeProfile = System.getProperty(SPRING_PROFILES_ACTIVE);
            if (activeProfile == null) {
                activeProfile = "dev";
            }
            PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer
                    = new PropertySourcesPlaceholderConfigurer();
            Resource[] resources = new ClassPathResource[]
                    {new ClassPathResource("application.properties"),
                            new ClassPathResource("application-" + activeProfile + ".properties")};
            propertySourcesPlaceholderConfigurer.setLocations(resources);

        }
    }

How to read System environment variable in Spring Boot, When Spring Boot initializes its environment, it uses properties files, YAML files, use the @Value annotation to load variables from the application.properties. In this post, we will see how to read system environment variable (OS level variables) in a Spring Boot application. When Spring Boot initializes its environment, it uses properties files, YAML files, environment variables, and command-line arguments to externalize the configuration.

Flayway don't recognize the direct environment variables into the application.properties (Spring-Boot V2.1). e.g

spring.datasource.url=jdbc:mysql://${DB_HOSTNAME}:${DB_PORT}/${DB_DATABASE}
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASS}

To solve this issue I did this environment variables, usually I create the file .env:

SPRING_DATASOURCE_URL=jdbc:mysql://127.0.0.1:3306/place
SPRING_DATASOURCE_USERNAME=root
SPRING_DATASOURCE_PASSWORD=root

And export the variables to my environment:

export $(cat .env | xargs)

And finally just run the command

mvn spring-boot:run

Or run your jar file

java -jar target/your-file.jar

There another approach here: https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/maven-plugin/examples/run-env-variables.html

Java System.getProperty vs System.getenv, Learn exactly how to use getProperty and getenv with java.lang. the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2: Environment Variables are key/value pairs like Properties. Quoting the documentation: Spring Boot allows you to externalize your configuration so you can work with the same application code in different environments. You can use properties files, YAML files, environment variables and command-line arguments to externalize configuration. Property values can be injected directly into your beans using the @Value annotation, accessed via Spring’s Environment abstraction or bound to structured objects via @ConfigurationProperties.

Properties with Spring and Spring Boot, Tutorial for how to work with properties files and property values in Spring Boot will also detect environment variables, treating them as  I have a spring boot application which interacts with DB to provide resource using Spring data Rest. I want to get the configuration from environment variables. Below is my properties file. spring.

indrekots/spring-boot-envvariables: Example on how to use , Using env variables with Spring Boot. This is an example application which demonstrates how to configure a Spring Boot app via environment variables. A Spring Boot application can be deployed in a variety of environments and reading environment variables can be helpful in such cases. Tweet Spring is a popular Java application framework and Spring Boot is a next step of evolution of Spring which helps create stand-alone, production-grade Spring based applications with minimal effort.

Spring Boot : Integration tests with environment variables, If you want to read about setting up an EmailService which reads the credentials from environment variables please refer to my article on: It can  Throughout this tutorial, we'll use a small (5MB) Linux image called Alpine. Let's start by pulling the image locally: docker pull alpine:3. When we launch our Docker container, we can pass environment variables as key-value pairs directly into the command line using the parameter –env (or its short form -e).

Comments
  • Read @ConfigurationProperties to learn more. However, this is a perfect use case for Profile specific configuration properties
  • This method is more convenient for docker linking. For instance: docker run --name my-tomcat -p 127.0.0.1:8080:8080 -e APP_DB_DB=mydb -e APP_DB_USER=dbuser -e APP_DB_PASS=dbpass --link mongo-myapp:mongo -v /path-to/tomcat/webapps:/usr/local/tomcat/webapps -d tomcat:8-jre8-alpine
  • This is absolutely the best way to go. Using environment variables means you don't need to list secrets in plain text along side your application. This is significantly more secure and reduces dependency on your source code access security measures to protect your entire estate. An accidental SO post with properties included doesn't result in information leaking out.
  • I wanted to add to this and mention that if you are using spring boot(didn't check if it works without boot), then any property can be overriden via an environment variable automatically without modifying your application.properties. ie, if you have a property called spring.activemq.broker-url then the corresponding environment variable would be: SPRING_ACTIVEMQ_BROKER_URL. periods and dashes are automatically converted to underscores. This is extremely convenient when working with containers/spring boot.
  • If you design for cloud it's not a preferable way to use Spring profiles. Using environment variables is recommended by the 12 factor app standard: 12factor.net/config
  • I know this topic is a bit old. But you can combine both environment variable setup and spring profile setup. You dev profile should have static information while your production profile can make use of the environment variables. In this way dev's no longer need to define environment variables on their machine if they just want to deploy the development profile.
  • I like this answer, but what if you want the profile name to come from the environment? I've tried -Dspring.active.profiles=$SPRING_ACTIVE_PROFILES, and setting the OS env var in /etc/profile.d/myenvvars.sh, but Spring Boot doesn't pick that up
  • SPRING_PROFILES_ACTIVE works because of the relaxed binding feature of spring boot docs.spring.io/spring-boot/docs/1.3.0.BUILD-SNAPSHOT/reference/…
  • thanks for this answer Stefan, it worked for me, but with one change - the property is actually spring.profiles.active and not spring.active.profiles
  • Whilst Spring profiles can be very useful, in relation to the OP they aren't suitable. This is due to how source code is stored and sensitivity of the properties information stored with that. The OP context is around Database access. For that situation you don't want prod details in plain text in source. This means if the source is compromised then the database is also compromised. It is better to use env variables or secret tools for this instead such as Vault. I prefer env. I'd also make all environments operate the same way in this regards for consistency. It avoids accidents in the future.
  • You can use a Spring Boot profile properties file external to the application JAR. This environment-specific file, for instance, application-production.properties, would be deployed to the production machine in a secure way, and would not typically be in the application source code repository.
  • Doesn't Spring Boot handle this scenario out of the box? See External Config documentation here
  • What is env-vars? How are they used. Your answer refers to things without a complete description and you do not include any links. I almost downvoted this, but I see your rep is 21 so you are new and one person found your answer useful, so I let it go, but try to provide more information in future answers, and welcome to SO (Stack Overflow). I hope you enjoy it as much as I do.
  • Thanks @PatS, I added more details, hope it will useful.
  • Excellent changes. Thanks updating your answer.