spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

Investigate developer specific profile / properties support

Open philwebb opened this issue 1 year ago • 2 comments
trafficstars

There have been a few issues relating to developer specific properties or profiles. The requests tend to be a variation of "when I run my app locally I want a developer profile active, when in production I do not". See #25712 #32479 #39156.

philwebb avatar Aug 30 '24 17:08 philwebb

I tackled it by:

		if (ClassUtils.isPresent("org.springframework.boot.devtools.RemoteSpringApplication",
				DemoApplication.class.getClassLoader())) {
			String profiles = System.getProperty(ACTIVE_PROFILES_PROPERTY_NAME);
			if (profiles == null) {
				profiles = System.getenv(ACTIVE_PROFILES_PROPERTY_NAME.replaceAll("\\.", "_").toUpperCase());
				if (profiles == null) {
					System.setProperty(ACTIVE_PROFILES_PROPERTY_NAME, "dev");
				}
			}
		}

I wish Spring Boot would provide an official solution.

quaff avatar Sep 03 '24 07:09 quaff

Just as a data point for discussions, we have core plugins/libraries that do the following:

  • enable local and dev profiles on BootRun task.
  • support encoded/encrypted property values (more obscurity than security)
  • @LocalIntegrationTest meta-annotation to (among other things) apply local/dev profiles for tests using/needing dev-integration environment access

The application.properties file is used exclusively for config/defaults which can safely apply to any/all environments. Crucially, this prevents the application from running in an environment where we have failed to configure properties properly: e.g. silently falling back to dev-integration credentials someone put in application.properties in production because we are missing or failed to inject the needed production properties.

Projects will usually have an application-local.properties file in source control which provides dev/CI access to the dev-integration environment where needed. Secrets in these files may be encoded/encrypted to obscure them, but nothing truly secret: we generally consider most dev-integration credentials not "super-secret" and want/need CI tests to run without build-agent configuration.

The application-dev.properties file is excluded from source control and can be used/required for access to more secure integration points when developers run locally or execute integration tests excluded from the CI build. Applications are still expected to bootRun/test without these properties by using mocks/stubs or disabling modules.

We have other patterns for pulling secure, environment-specific dev-test credentials from user home -- primarily for dev testing and triage -- but don't automatically pull any external properties files into all applications to avoid collisions/confusion because, for one example, which spring.datasource.url is appropriate may vary by application.

It's all a non-obvious mess we are constantly tinkering with, so I agree generally it would be nice to have something built-in that, at a minimum, discouraged configuring secrets/integration points in application.properties and standardized some pattern of locations (on-and-off-the-classpath? generic and application-name-specific if outside application folder?) where these can be kept when running locally (bootRun or manually enabled when running jar from command-line) and in integration tests.

jeffbswope avatar Sep 03 '24 14:09 jeffbswope

In my library (see docs), I provide two profiles out-of-the-box that are enabled when running the application in development mode (dev) and when running tests (test). I made them configurable since different teams have different conventions (e.g. local instead of dev). Multiple profiles are also supported for both development and test modes. By doing this, I also solve the problem described in https://github.com/spring-projects/spring-boot/issues/38098

To achieve this, I relied on an ApplicationListener (code here). I don't know if it's the best way to solve this problem, but it works quite effectively.

The library is included in a project only for development and test, so there is no risk to include dev/test config in the final production artefact. For example, in Gradle:

dependencies {
  testAndDevelopmentOnly 'io.arconia:arconia-dev-tools'
}

Furthermore, the whole feature can be turned off via properties.

ThomasVitale avatar Apr 07 '25 22:04 ThomasVitale