When developing enterprise applications with Spring Boot, managing multiple environments is a necessity. You need different configurations for development, testing, staging, and production, but hardcoding settings or maintaining separate codebases is a disaster waiting to happen.
Spring Boot’s Profiles feature allows you to define environment-specific configurations that seamlessly switch based on where the application runs.
In this guide, you’ll learn how to use Spring Boot Profiles like a seasoned engineer, covering:
- Why Profiles are essential
- How to configure properties for multiple environments
- How to switch between them
- Advanced usage with YAML, @Profile, and command-line arguments
Watch the Video Tutorial
Want a step-by-step walkthrough? Watch my YouTube video where I explain everything in detail!
Why Do You Need Spring Boot Profiles?
Imagine you have these environments:
Environment | Database | Logging Level | API URL |
---|---|---|---|
Dev | PostgreSQL | DEBUG | https://dev-api.example.com |
Staging | PostgreSQL | INFO | https://staging-api.example.com |
Production | PostgreSQL | ERROR | https://api.example.com |
Without Spring Boot Profiles, you’d have to manually change configurations before each deployment. That’s not just error-prone—it’s unacceptable in real-world applications.
Configuring Profiles with Property Files
The easiest way to use profiles is by defining environment-specific .properties
or .yaml
files.
1. Using .properties
Files
Spring Boot loads properties from application.properties
by default. But you can create environment-specific property files:
application-dev.properties
application-staging.properties
application-prod.properties
Each file contains environment-specific settings:
src/main/resources/application-dev.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=username
spring.datasource.password=password
logging.level.org.springframework=DEBUG
app.api.url=https://dev-api.example.com
src/main/resources/application-prod.properties
spring.datasource.url=jdbc:postgresql://prod-db:5432/mydb
spring.datasource.username=prod_user
spring.datasource.password=securePassword
logging.level.org.springframework=ERROR
app.api.url=https://api.example.com
Spring Boot will automatically pick the correct file based on the active profile.
How to Set the Active Profile
1. Using application.properties
(Default Profile)
If no profile is specified, Spring Boot loads application.properties
.
To explicitly set a default profile, add this in application.properties
:
spring.profiles.active=dev
2. Using Command-Line Arguments
You can set the profile dynamically at runtime:
java -jar myapp.jar --spring.profiles.active=prod
This method is commonly used in CI/CD pipelines and production deployments.
3. Using Environment Variables (Best for Containers/Kubernetes)
For Docker and Kubernetes deployments, you can use an environment variable:
export SPRING_PROFILES_ACTIVE=staging
Using YAML for Profile-Based Configuration
If you prefer YAML, you can either do the same thing as properties (have one file per env) or can define all environments on a single one:
application.yml
spring:
profiles:
active: dev # Default profile
---
spring:
config:
activate:
on-profile: dev
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: username
password: password
logging:
level:
org.springframework: DEBUG
app:
api:
url: <https://dev-api.example.com>
---
spring:
config:
activate:
on-profile: prod
datasource:
url: jdbc:postgresql://prod-db:5432/mydb
username: prod_user
password: securePassword
logging:
level:
org.springframework: ERROR
app:
api:
url: <https://api.example.com>
This YAML setup ensures that Spring Boot automatically loads the correct configuration when switching profiles.
Using @Profile
to Load Beans Based on the Active Profile
Spring Boot also lets you define beans that only load for specific profiles.
Example:
Define two different DataSource
beans, one for dev and one for production.
@Configuration
public class DataSourceConfig {
@Bean
@Profile("dev")
public DataSource h2DataSource() {
System.out.println("Loading H2 DataSource for Dev");
return new HikariDataSource(new HikariConfig("/h2-datasource.properties"));
}
@Bean
@Profile("prod")
public DataSource postgresDataSource() {
System.out.println("Loading PostgreSQL DataSource for Prod");
return new HikariDataSource(new HikariConfig("/postgres-datasource.properties"));
}
}
When the app runs:
- If
dev
is active, it loads the H2 database. - If
prod
is active, it loads PostgreSQL.
This approach eliminates unnecessary beans and improves performance.
Best Practices for Managing Spring Boot Profiles
- Never commit sensitive credentials in properties files.
- Use environment variables or secrets management tools (e.g., AWS Secrets Manager, HashiCorp Vault).
- Always set a default profile (
spring.profiles.active=dev
).- Prevents unexpected behavior when running locally.
- Use
@Profile
to optimize performance.- Avoids loading unnecessary beans in production.
- Use command-line arguments for CI/CD pipelines.
- Ensures the right profile is active during deployments.
- Document your profiles in
README.md
.- Make it easy for new developers to understand the environments.
Conclusion
Spring Boot Profiles are a powerful and flexible way to manage configurations across multiple environments.
By following the best practices outlined here, you can effortlessly switch environments and deploy confidently without modifying your code.