environment variables
application.yml
configuration management
Spring Boot
YAML files

Does application.yml support environment variables?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Yes, Spring Boot supports environment variables in application.yml. In practice, this happens in two related ways: Spring can resolve placeholders such as ${DB_HOST} inside YAML values, and Spring's externalized configuration system can also bind environment variables directly to properties without you writing placeholders at all. Understanding the difference makes configuration cleaner and easier to debug.

Placeholder Syntax in application.yml

The most familiar pattern is the placeholder form:

yaml
1server:
2  port: ${SERVER_PORT:8080}
3
4spring:
5  datasource:
6    url: jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:app}
7    username: ${DB_USER:app}
8    password: ${DB_PASSWORD:secret}

This tells Spring:

  • use the environment variable if it exists
  • otherwise fall back to the default after the colon

If no default is given and the variable is missing, the property may fail to resolve depending on how it is consumed.

This is the most explicit way to make environment dependencies visible in the file.

Direct Binding Without ${...}

Spring Boot also maps environment variables into property names automatically. For example, the environment variable:

text
SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/app

can satisfy the property spring.datasource.url without you writing ${SPRING_DATASOURCE_URL} in YAML. That is part of Spring Boot's relaxed binding rules.

A few examples of the mapping style:

  • 'SPRING_DATASOURCE_URL maps to spring.datasource.url'
  • 'SERVER_PORT maps to server.port'
  • 'MY_APP_FEATURE_ENABLED maps to my.app.feature-enabled'

This is why many production deployments keep sensitive values entirely outside application.yml and let Spring bind them from the environment.

A Small Spring Example

Here is a minimal Java example that reads a property injected from either YAML or the environment:

java
1import org.springframework.beans.factory.annotation.Value;
2import org.springframework.boot.CommandLineRunner;
3import org.springframework.boot.SpringApplication;
4import org.springframework.boot.autoconfigure.SpringBootApplication;
5
6@SpringBootApplication
7public class DemoApplication implements CommandLineRunner {
8
9    @Value("${app.greeting:Hello}")
10    private String greeting;
11
12    public static void main(String[] args) {
13        SpringApplication.run(DemoApplication.class, args);
14    }
15
16    @Override
17    public void run(String... args) {
18        System.out.println(greeting);
19    }
20}

With this YAML:

yaml
app:
  greeting: ${APP_GREETING:Hello from YAML}

And this shell command:

bash
export APP_GREETING="Hello from environment"
./mvnw spring-boot:run

the environment value wins.

Property Source Precedence Matters

Spring Boot does not treat every source equally. Command-line arguments, environment variables, application files, and profile-specific files all participate in an ordered precedence model.

The practical consequence is that an environment variable can override a value defined in application.yml, which is exactly what many deployment pipelines rely on.

That makes application.yml a good place for:

  • sensible local defaults
  • documented property names
  • non-secret configuration

and the environment a good place for:

  • secrets
  • deployment-specific values
  • container-orchestrator injected configuration

Profiles and Environment Variables Work Together

You can combine profiles with placeholders. For example, a production profile might still use environment variables for secrets.

yaml
1spring:
2  config:
3    activate:
4      on-profile: prod
5
6management:
7  endpoints:
8    web:
9      exposure:
10        include: health,info
11
12app:
13  api-key: ${APP_API_KEY}

This keeps the profile structure in YAML while leaving sensitive runtime values outside source control.

Common Pitfalls

A common mistake is assuming placeholders are the only way Spring Boot reads environment variables. Direct environment binding also works.

Another mistake is forgetting default values for optional settings. Without a default, a missing variable can surface as a startup failure later than expected.

People also sometimes mismatch property names and environment variable names. spring.datasource.url maps naturally to SPRING_DATASOURCE_URL, not to an arbitrary custom variable name unless you reference it explicitly with ${...}.

Finally, be careful with quoting and special characters in shell environments, especially for passwords and JDBC URLs.

Summary

  • 'application.yml supports environment variables through ${VAR} and ${VAR:default} placeholders'
  • Spring Boot can also bind environment variables directly to property names without placeholders
  • Environment variables typically override values defined in application.yml
  • Use YAML for defaults and documentation, and use environment variables for deployment-specific values and secrets
  • Relaxed binding lets names such as SPRING_DATASOURCE_URL map to spring.datasource.url
  • Add defaults where appropriate so missing variables fail predictably rather than mysteriously

Course illustration
Course illustration

All Rights Reserved.