I need to oveeride some of properties defined in a application.yml of Spring Boot application running in k8s. How can I do this? The only way I found is to mount whole application.yml but I only need to override one property.
-
Is setting the single property as an environment variable (without necessarily involving a ConfigMap) a viable approach for you? – David Maze Feb 13 '21 at 12:10
-
@DavidMaze I'm afraid no – x__dos Feb 13 '21 at 12:29
3 Answers
Could be doable in another way, that's why i'm answering again. Do it in an easy way.
Create your application.yml in a configmap and mount it as a sub directory called config into the same directory where the spring boot jar ins located.
The documentation of spring boot (external application properties) says:
Spring Boot will automatically find and load application.properties and application.yaml files from the following locations when your application starts:
The classpath root
The classpath /config package
The current directory
The /config subdirectory in the current directory
Immediate child directories of the /config subdirectory
Which means we don't have to take care of setting anything. It should find the config inside the subdirectory config.
apiVersion: v1
kind: ConfigMap
metadata:
name: spring-application-config
data:
application.yml: |
spring:
application:
name: This is just an example, add as many values as you want.
pod.yaml:
...
volumeMounts:
- name: spring-application-config
mountPath: /app/config
- name: spring-application-config
configMap:
name: spring-application-config
...
Assuming that your spring boot jar file is located in the path /app

- 1,928
- 2
- 16
- 26
Spring Boot Apps should override properties in the configuration files (aka, in their application.yml most of the times) with environment variables.
Assuming the App is deployed on Kubernetes with a Pod (but it doesn't matter, Deployments, StatefulSets, Jobs are all the same regarding environment) you can inject environment variables inside the container by either directly assigning them to the Deployment itself, or with a ConfigMap (or a Secret, should the property be more secure and masked)
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
containers:
- name: example-container
image: example-image:latest
env:
- name: THIS_IS_AN_ENV_VARIABLE
value: "Hello from the environment"
- name: spring.persistence.url
value: "The persistence url, for example"
Even better, you can inject all the content of a ConfigMap as environment variables:
apiVersion: v1
kind: ConfigMap
metadata:
name: example-config
data:
spring.persistence.url: "your persistence url"
spring.mail.user: "your mail user"
And then your Pod:
apiVersion: v1
kind: Pod
metadata:
name: example
spec:
containers:
- name: example-container
image: example-image:latest
envFrom:
- configMapRef:
name: example-config
Inside the container, the variables will be in the environment.. and Spring should use them to override variables with same name which are defined (or maybe not even defined) in your application.yml
For more info:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/ https://docs.spring.io/spring-boot/docs/1.3.3.RELEASE/reference/html/boot-features-external-config.html

- 2,281
- 1
- 8
- 22
We had to do something similar. And i explain you how we did. Possibly this helps.
If you can modify your Dockerfile then create an entrypoint.sh script. It could contain the following:
entrypoint.sh
#!/bin/bash
set -e
# Source custom scripts, if any
if [ -d /etc/spring.d ]; then
for f in /etc/spring.d/*; do
if [ -x "$f" ]; then
echo "Running $f ..." >&2
"$f"
else
echo "Could not run $f, because it's missing execute permission (+x)." >&2
fi
done
unset f
fi
exec "$@"
The entrypoint.sh is executing custom scripts inside the /etc/spring.d directory on startup. You can put any exectuble script inside, whatever you want.
Inside the /etc/spring.d you can create a copy script which copies an application.yml into same directory where the spring boot jar file is located. Example follows.
Your Dockerfile could look like
FROM adoptopenjdk:15-jre
RUN mkdir /app
COPY application.jar /app/
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["java", "-jar", "/app/application.jar"]
If this is prepared, you can use a configMap to define the copy script and mount it to the directory /etc/spring.d
apiVersion: v1
kind: ConfigMap
metadata:
name: spring-d
data:
copy-yaml.sh: |
#!/bin/bash
cp /config/application.yml /app/application.yml
The copy script will take care, that you application.yaml (which will be mounted as a configMap as well) will be copied to the right place.
And a further configMap for your application.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-yaml
data:
application.yml: |
spring:
application:
name: This is just an example, add as many values as you want.
Inside your pod yaml you could do something like this:
...
volumeMounts:
- name: spring-d
mountPath: /etc/spring.d
- name: app-yaml
mountPath: /config
- name: spring-d
configMap:
name: spring-d
defaultMode: 0777
- name: app-yaml
configMap:
name: app-yaml
...
THIS CODE IS CURRENTLY UNTESTED, IT'S JUST SHOWING YOU AN EXAMPLE HOW YOU COULD SOLVE YOUR PROBLEM IN A VERY FLEXIBLE WAY.
I used snippets from my scripts and copied it here together, so maybe there could be small mistakes inside. Please let me know.

- 1,928
- 2
- 16
- 26