Spring Boot Profiles for Multi-Environment Configuration

Introduction

Real projects run in multiple environments: local development, testing, staging, and production. Each environment needs different settings (database URL, logging level, feature flags), but your Java code should stay the same. In this chapter, you will learn how to use Spring Boot profiles to switch configuration safely and predictably.

Prerequisites

  • Completed:
    • 01_what_is_spring_boot.md
    • 02_installing_java_maven_and_idea.md
    • 03_create_first_spring_boot_project.md
    • 04_application_properties_and_yaml_basics.md
  • Familiarity with application.properties or application.yml

What Is a Profile?

A profile is a named configuration set for one runtime context.

Typical names:

  • dev for local development
  • test for automated tests / QA
  • prod for production deployment

Instead of editing one config file over and over, you define separate files and activate the profile you need.

Profile File Naming

Spring Boot recognizes profile-specific files:

text
src/main/resources/
  application.yml
  application-dev.yml
  application-test.yml
  application-prod.yml

Or the .properties style:

text
application.properties
application-dev.properties
application-test.properties
application-prod.properties

application.yml (or .properties) is the base file. Profile files override only what changes per environment.

Example Configuration

Base file: application.yml

yaml
spring:
  application:
    name: demo-service
 
server:
  port: 8080
 
app:
  greeting: Hello from base config

Development file: application-dev.yml

yaml
server:
  port: 8081
 
logging:
  level:
    root: DEBUG
 
app:
  greeting: Hello from DEV

Production file: application-prod.yml

yaml
server:
  port: 8080
 
logging:
  level:
    root: INFO
 
app:
  greeting: Hello from PROD

Activate a Profile

You can activate profiles in several ways.

1) In base config file

yaml
spring:
  profiles:
    active: dev

This is convenient for local development, but many teams avoid committing a fixed active profile in shared repos.

bash
mvn spring-boot:run -Dspring-boot.run.profiles=dev

or:

bash
java -jar target/demo-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod

3) Environment variable

  • SPRING_PROFILES_ACTIVE=dev

Great for Docker and deployment platforms.

Tip

Production-Friendly Practice

Keep profile activation outside source code (env vars or deployment args) for production workloads.

How Merging Works

Spring Boot merges base + active profile config:

  1. Load base config (application.yml)
  2. Load active profile file (application-dev.yml)
  3. Profile file overrides matching keys

If a key exists only in base, base value is used.
If a key exists in both, active profile value wins.

Verify Active Profile at Runtime

Add a quick endpoint:

Code explanation:

  • ${spring.profiles.active:default} returns active profile or fallback default
  • app.greeting helps verify whether dev/prod override worked

Multiple Active Profiles

You can activate more than one profile:

bash
--spring.profiles.active=dev,cloud

Use this carefully. Precedence follows order and source rules; complexity grows quickly.

For beginners, prefer one active profile at a time (dev, test, or prod).

Profile Groups (Useful in Larger Projects)

Spring Boot supports grouping profiles:

yaml
spring:
  profiles:
    group:
      production: prod,metrics,security

Then activate one logical profile:

bash
--spring.profiles.active=production

Useful when many modules share deployment behavior.

Common Mistakes and Fixes

Profile file not loaded

Checklist:

  • File name exact? (application-dev.yml, not application_dev.yml)
  • File in src/main/resources?
  • Active profile actually set?

Wrong value still appears

Likely overridden by higher precedence source:

  • Command-line args
  • Environment variables
  • External config file mounted in runtime

Secrets committed to repo

Do not put production passwords in Git-tracked profile files.

Better:

  • Keep placeholders in profile files
  • Inject sensitive values through env vars or secret stores

Warning

application-prod.yml is not a safe place for raw production credentials. Treat source control as potentially readable and keep secrets external.

Best Practices

  • Use clear profile names: dev, test, staging, prod
  • Keep base config minimal and environment-neutral
  • Put only differences in profile files
  • Activate profile via environment/deployment config, not hardcoded in app code
  • Keep logging more verbose in dev, stricter in prod

Quick Recap

In this chapter, you learned how to:

  1. Separate config by environment using profiles
  2. Activate profiles through config, CLI, or env vars
  3. Understand base + override merge behavior
  4. Avoid common profile mistakes in team projects

Next, you will start deepening web-layer fundamentals with Spring MVC annotations and request mapping patterns.

FAQ

Do I always need a prod profile?

In most real systems, yes. It helps isolate production-safe settings from local defaults.

Can I run without setting any profile?

Yes. Spring Boot uses the default (base) configuration when no profile is active.

Should I commit spring.profiles.active=dev?

Usually no for shared repos. It can surprise teammates and CI pipelines. Prefer environment-specific activation.

How many profiles are too many?

If profile combinations become hard to reason about, simplify. Start with dev, test, and prod, then evolve only when needed.

Are profiles the same as feature flags?

Not exactly. Profiles are coarse environment-level configuration. Feature flags are usually finer-grained runtime toggles.