By now your app runs in more than one place: on your laptop, in your Docker Compose stack, and live in the cloud. These environments are not identical. Locally you want verbose logs to see what is happening; in production you want them quiet. You might load fake test data on your machine, but never in production.
Hardcoding one set of values means editing code every time you switch. Spring profiles solve this: you define named sets of configuration β usually dev and prod β and choose one at startup. Same code, same image, different behaviour.
<aside> π‘
This continues the "same image, different configuration" idea from the Docker Compose and Deploying to the Cloud chapters. Profiles are the Spring-native way to organise those differences.
</aside>
Spring Boot loads application.yaml in every environment. On top of that it loads one profile-specific file named application-<profile>.yaml, whose values win.
src/main/resources/
application.yaml # shared defaults, always loaded
application-dev.yaml # loaded when the "dev" profile is active
application-prod.yaml # loaded when the "prod" profile is active
application.yaml β shared by all environments:
logging:
level:
root: INFO
application-dev.yaml β noisy logs for local work:
logging:
level:
root: DEBUG
org.springframework.jdbc.core: DEBUG # log every SQL statement
application-prod.yaml β quiet logs in production:
logging:
level:
root: WARN
When the dev profile is active, Spring merges application.yaml + application-dev.yaml. Nothing from prod is loaded.
You already know the mechanism β an environment variable:
SPRING_PROFILES_ACTIVE=dev
Set it wherever the app starts:
environment: block of your api service, next to your other variables.SPRING_PROFILES_ACTIVE=prod in the Environment tab, next to your database variables.<aside> π
If you set no profile, only application.yaml is loaded β no dev or prod file. That is your safe default.
</aside>
π¬Β Question: You put your Neon database password in application-prod.yaml so it is ready for production. What is wrong with that?
This is the important part, and it is the discipline this course follows:
DATABASE_URL, passwords, API keys β exactly as you set them in Docker Compose and on Render.So a prod profile might turn logging down to WARN, while the production database URL and password still arrive as environment variables. Profiles decide how the app behaves; env vars supply the sensitive values.
<aside> β
Never put a password, token, or connection secret in any application-*.yaml file. If it is in the file, it is in Git, and it is leaked.
</aside>
Profiles are not limited to config files. You can annotate a whole component so it loads only in a chosen environment:
@Component
@Profile("dev")
public class DataSeeder {
// insert fake data on startup β handy locally, never in production
}
With @Profile("dev"), this bean exists when the dev profile is active and is simply absent otherwise.
@Profile and how to activate profiles.The HackYourFuture curriculum is licensed underΒ CC BY-NC-SA 4.0 *https://hackyourfuture.net/*

Built with β€οΈ by the HackYourFuture community Β· Thank you, contributors
Found a mistake or have a suggestion? Let us know in the feedback form.