[← Seeing precedence](03-seeing-precedence.md) · [Index](../README.md) · [Config import →](05-config-import.md) # 4. Why your profile-specific file lost Transcript: [`02-profile-file-loses.txt`](output/02-profile-file-loses.txt). The bug: you set a value in `application-prod.yaml`, deploy with `prod` active, and the old value is still in effect. ## Two runs, one difference ``` --- 1. prod profile active, no environment variable --- effective value : jdbc:postgresql://prod-db:5432/orders 1. jdbc:postgresql://prod-db:5432/orders <- application-prod.yaml 2. jdbc:h2:mem:default <- application.yaml ``` Working as intended. Now with one leftover variable in the environment: ``` --- 2. identical, plus one leftover environment variable --- effective value : jdbc:postgresql://leftover:5432/orders 1. jdbc:postgresql://leftover:5432/orders <- systemEnvironment 2. jdbc:postgresql://prod-db:5432/orders <- application-prod.yaml 3. jdbc:h2:mem:default <- application.yaml ``` The profile file was still loaded. It still holds the right value. It is at rank 2. ## Why it feels wrong Profile-specific files *do* override — the mental model is not wrong, it is incomplete. They override other config data. Config data as a whole sits at item 3 in the precedence list and environment variables at item 5, so the strongest file loses to the weakest variable. ## Where the leftover variables come from Every one of these is real: - A Kubernetes `Deployment` with an `env:` block that predates the ConfigMap and was never removed. `envFrom` a `ConfigMap` produces environment variables, not config data. - A `docker-compose.yml` `environment:` entry copied from a colleague. - Spring Cloud Kubernetes or a service mesh injecting `SPRING_DATASOURCE_URL`. - A CI runner exporting variables for a different service. - `SPRING_APPLICATION_JSON`, which is item 10 and beats almost everything. ## Diagnosing it in one step If a property is not what the file says, look for a variable: ```bash kubectl exec deploy/my-app -- env | grep -i datasource ``` or ask the running application, which reports every holder including the one you did not know about. ## Living with it **Prefer environment variables in containers, files for defaults.** The precedence order is designed for exactly this: the image carries defaults, the deployment overrides them. Fighting it means fighting the design. **Do not set the same key in both places.** If a value is per-environment, keep it out of the profile files entirely so there is only ever one source. **Name environment variables specifically.** `DEMO_DATASOURCE_URL` collides with nothing; `SPRING_DATASOURCE_URL` collides with every Spring application on the host. **Mount configuration as a config tree instead.** Still config data, still below environment variables, but at least it is one mechanism rather than two — [chapter 6](06-config-trees-and-configmaps.md).