Currently environment variables get bound to @Configuration properties directly (for example SERVER_PORT to Server.port). This can cause problems when trying to set ignoreInvalidFields or if you want to run two different boot apps as the same user.

@gregturn suggested that we consider supporting a prefix when binding. For example:

springApplication.setEnvironmentPrefix("MYAPP_");
...

Which would then bind MYAPP_SERVER_PORT rather than SERVER_PORT.

Comment From: snicoll

I like that.

Comment From: lucassaldanha

+1 for this feature!

Comment From: lucassaldanha

Here is what I thought:

At the SpringApplication.configurePropertySources(..) we can filter the environment.getSystemEnvironment() map and replace it with a new one just with the properties which keys start with the prefix.

I though about something like this:

protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
    ...
    if(this.environmentPrefix != null && !this.environmentPrefix.equals("")) {
        filterSystemEnvironmentPropertySourceByPrefix(environment);
    }
    ...
}

private void filterSystemEnvironmentPropertySourceByPrefix(ConfigurableEnvironment environment) {
    final Map<String, Object> systemEnvironment = environment.getSystemEnvironment();
    final Map<String, Object> prefixedSystemEnvironment = new HashMap<String, Object>(systemEnvironment.size());
    for(String key : systemEnvironment.keySet()) {
        if(key.startsWith(environmentPrefix)) {
            prefixedSystemEnvironment.put(key.substring(environmentPrefix.length()), systemEnvironment.get(key));
        }
    }   

    environment.getPropertySources().replace(
        StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
        new SystemEnvironmentPropertySource(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, prefixedSystemEnvironment));
}

What do you think? There are any collateral damage doing this? I have tested myself and it seems o work quite well. If you want I can make a Gist or a PR with my code.

Comment From: mageddo

I personally prefer something like that

application.properties

my.prefix.name=Elvis

Config.java

@Bean
public MyBean myBean(@ConfigurationProperties(prefix="my.prefix") Environment env) {
    env.getProperty("name");
....

Can it be implemented at this issue??

Comment From: philwebb

@mageddo This issue is specifically for adding a prefix to system environment variable. You example can't be implemented because we already support @ConfigurationProperties on @Bean methods (meaning bind properties the resulting bean). If you have questions please join us on Gitter or ask on stackoverflow.com.

Comment From: mcompton13

@philwebb, @snicoll, I've got a proposed fix for this change where I've slightly modified the classes that do the @ConfigurationProperties binding so to make it easy to add a prefix when looking up properties from the Environment source as suggested in this comment: https://github.com/spring-projects/spring-boot/pull/3480#issuecomment-121143402.

I've never submitted anything to the Spring project, so I was looking for some guidance before I submit my code for review so hopefully I get it right the first time. I found this page: https://github.com/spring-projects/spring-boot/wiki/Working-with-Git-branches and it seems like I need to pick the right branch to start with. I'm working off of the 2.1 branch because that's what my project is using. Is the 2.1 branch OK for this enhancement or would you like me to start it off of a different branch?

Comment From: snicoll

@mcompton13 thanks for working on this. Please create a branch from master and submit your proposal. The wiki page is intended to the core team and is not related to external contributions.

Comment From: jwedel

@mcompton13 @lucassaldanha @snicoll @philwebb Any updates on this? As far as I understand, this has already been implemented but no merged?

Comment From: snicoll

@jwedel this issue is still open in the general backlog and I am not aware of an existing implementation.

Comment From: mcompton13

Sorry, when I added my comment I had worked through most of the implementation but I found later while I was working on the tests that my solution impacted the NoUnboundElementsBindHandler. Unfortunately more pressing things came up and I haven't had a chance to get back to finishing up my change.

I'm hoping to return to it soon.

Comment From: philwebb

We've renamed a lot of our own configuration properties since this was raised. The general shift to containers has also reduced the need for this feature.

Comment From: vpavic

Please consider adding support for this.

There are still plenty of Spring Boot based projects operating in environments which developers have little to no control over. I've been in this situation several times over the years and the ability to prefix the environment variables would make life easier.

An example: customer insisting on deploying multiple Spring Boot applications to the same WildFly instance, with each application using its own database - which makes using SPRING_DATASOURCE_* properties impossible to use without workarounds.

Comment From: philwebb

Well that didn't last long :) I'll reopen it again.

Comment From: jwedel

Yup. We have multiple deployments, some with docker and some on premise.

For the latter, we created our own prefixed env variables of the most used spring ones and then used them as default values in the properties file. But that is very limiting and we cannot change others without rebuilding the application.

Comment From: lucassaldanha

Wow! It's been a few years since I first touched this. I'll give it a go later today! 👍

Comment From: rsenden

Some environments add some standard prefix when setting environment variables. As an example, the GitHub Actions ecosystem uses environment variables with an INPUT_ prefix; a GitHub Actions input parameter named my-config-property will result in an INPUT_MY_CONFIG_PROPERTY environment variable being set.

In my Spring Boot applications I have implemented a somewhat hacky work-around for supporting this INPUT_ prefix if the application is running in GitHub; see https://github.com/spring-projects/spring-boot/issues/24202 for details. It would be nice if Spring Boot would support such (conditional) prefixes out of the box.