In Spring Boot, a profile is a way to segregate parts of your application configuration so that you can use different configurations for different environments, such as local, development (dev), staging, and production (prod). By setting up profiles, you can ensure that the appropriate beans, properties, and configurations are loaded based on the active environment.
Why Use Profiles in Spring Boot?
- Separation of Concerns: Each environment (e.g., local, dev, staging, prod) often has different requirements, such as different databases, logging levels, or security settings.
- Centralized Configurations: Spring Boot profiles help you keep all environment-specific configurations in a single place without the need to create multiple application versions.
- Smooth Deployment: You can easily switch between environments without code changes—just by activating a profile.
Creating Profiles in Spring Boot
To create different profiles, you will typically use environment-specific configuration files like application-{profile}.properties
or application-{profile}.yml
. These files contain the configurations unique to each environment.
Step 1: Define Environment-Specific Configuration Files
For each environment (local, dev, staging, and prod), create a corresponding configuration file.
File Structure:
application.properties
orapplication.yml
: Global settings (default profile).application-local.properties
: Local environment.application-dev.properties
: Development environment.application-staging.properties
: Staging environment.application-prod.properties
: Production environment.
Example: application-local.properties
:
1 2 3 4 5 6 7 8 9 10 |
# Local environment configuration spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password # Application specific properties server.port=8080 spring.jpa.hibernate.ddl-auto=update logging.level.org.springframework=DEBUG |
Example: application-dev.properties
:
1 2 3 4 5 6 7 8 9 |
# Dev environment configuration spring.datasource.url=jdbc:mysql://localhost:3306/devdb spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=devuser spring.datasource.password=devpass server.port=8081 spring.jpa.hibernate.ddl-auto=update logging.level.org.springframework=INFO |
Example: application-staging.properties
:
1 2 3 4 5 6 7 8 |
# Staging environment configuration spring.datasource.url=jdbc:mysql://staging-db-server:3306/stagingdb spring.datasource.username=staginguser spring.datasource.password=stagingpass server.port=8082 spring.jpa.hibernate.ddl-auto=validate logging.level.org.springframework=WARN |
Example: application-prod.properties
:
1 2 3 4 5 6 7 8 |
# Production environment configuration spring.datasource.url=jdbc:mysql://prod-db-server:3306/proddb spring.datasource.username=produser spring.datasource.password=prodpass server.port=8080 spring.jpa.hibernate.ddl-auto=none logging.level.org.springframework=ERROR |
Step 2: Activate Profiles
You can activate a profile in different ways:
1. In application.properties
(Default Profile):
Set a default profile to be active when none is specified:
1 2 |
# Default profile to use when no profile is specified spring.profiles.active=local |
2. Using Command-Line Argument:
You can specify the active profile while starting the application by passing the --spring.profiles.active
parameter.
1 2 3 4 5 |
# For local environment java -jar myapp.jar --spring.profiles.active=local # For dev environment java -jar myapp.jar --spring.profiles.active=dev |
3. Using Environment Variable:
You can set the active profile using an environment variable, which is useful for containerized or cloud-based environments.
1 |
export SPRING_PROFILES_ACTIVE=prod |
4. In IDE (e.g., IntelliJ, Eclipse):
If you are running your application from an IDE, you can set the profile in the Run/Debug Configurations by adding --spring.profiles.active=dev
or any other profile.
Step 3: Profile-Specific Beans
You can also use the @Profile
annotation to define beans that should only be created for a specific profile.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration public class DataSourceConfig { @Bean @Profile("local") public DataSource localDataSource() { return new H2DataSource(); // H2 in-memory database for local development } @Bean @Profile("dev") public DataSource devDataSource() { return new MySQLDataSource(); // MySQL for dev environment } @Bean @Profile("prod") public DataSource prodDataSource() { return new PostgresDataSource(); // Postgres for production } } |
In this case, Spring will load the correct DataSource
bean based on the active profile.
Step 4: Using Default and Multiple Profiles
Default Profile:
If you don’t specify a profile, Spring Boot will use the application.properties
file as the default configuration.
Multiple Profiles:
You can also activate multiple profiles at once by separating them with a comma:
1 |
spring.profiles.active=dev,staging |
In this case, Spring Boot will merge the configurations from both profiles, with the last one overriding values if there are conflicts.
Step 5: Spring Profile-Specific Application Logic
You can also conditionally execute logic based on the active profile by injecting the environment object into your code.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ProfileController { private final Environment environment; public ProfileController(Environment environment) { this.environment = environment; } @GetMapping("/activeProfile") public String getActiveProfile() { return "Active profile: " + String.join(", ", environment.getActiveProfiles()); } } |
This endpoint will return the currently active profiles of the running application.
Example Workflow: Local, Dev, Staging, Prod Environments
-
Local Development:
- Profile:
local
- Database: In-memory H2 database.
- Port:
8080
. - Purpose: Local testing and quick iterations.
- Profile:
-
Development:
- Profile:
dev
- Database: Local MySQL database or a shared dev database.
- Port:
8081
. - Purpose: Feature development and integration testing.
- Profile:
-
Staging:
- Profile:
staging
- Database: Separate staging environment.
- Port:
8082
. - Purpose: Pre-production testing and validation.
- Profile:
-
Production:
- Profile:
prod
- Database: Production database (MySQL/PostgreSQL).
- Port:
8080
or as required. - Purpose: Live environment for actual users.
- Profile:
Best Practices for Profiles in Spring Boot
-
Separate Configuration Files:
- Always maintain separate property files for different environments.
- This makes it easier to manage and override configurations.
-
Use Externalized Configurations:
- For sensitive data (like database passwords), use external configurations or environment variables to keep credentials out of source control.
-
Use Different Databases for Each Profile:
- In production, make sure you are using a real database (like MySQL, PostgreSQL) while for local development, you can use in-memory databases like H2 for fast testing.
-
Activate Profiles Through CI/CD Pipelines:
- When deploying via CI/CD pipelines (e.g., Jenkins, GitLab CI), activate profiles like
staging
orprod
to differentiate environments during build and deployment.
- When deploying via CI/CD pipelines (e.g., Jenkins, GitLab CI), activate profiles like
Summary
- Profiles in Spring Boot allow you to create different configurations for different environments like local, dev, staging, and prod.
- You can set up profile-specific configuration files (
application-{profile}.properties
) and activate them through various mechanisms (command line, environment variables, etc.). - Profiles help you manage database configurations, security settings, logging levels, and more, based on the target environment.
- Always test each profile-specific configuration before moving to the next environment to ensure smooth deployment.