Decoupling DB connection strings from spring boot api (K8s, Docker, Spring, Java)

4/10/2020

Problem: I have a VERY simple spring boot api with hard coded db connection strings. I would like to feed these connection strings FROM a pod in my K8s cluster but I am having issues with telling the api to read from env variables.

My Dockerfile:

FROM gcr.io/distroless/java:8
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

This is the db-secret.yaml file:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
data:
  host: XXXX
  user: XXXX
  password: XXXX
  database: XXXX

This is the env section of my api pod my deployment file:

          env:
            - name: ORIGIN
              value: https://myclient.app.com
            - name: HOST
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: host
            - name: PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: password
            - name: USERNAME
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: user
            - name: DATABASE
              valueFrom:
                secretKeyRef:
                  name: db-secret
                  key: database

This is my Java application.properties file:

spring.jpa.hibernate.ddl-auto=create
spring.datasource.url=${HOST}/"todos"
spring.datasource.username=${USERNAME}
spring.datasource.password=${PASSWORD}

However...when I try to build the app using ./mvnw clean package i get: * java.lang.IllegalStateException: Failed to load ApplicationContext * BeanCreationException: Error creating bean with name 'entityManagerFactory'

I tried exporting the variables via command line but that didn't work. I know node has process.env.SOME_VAR. Is there something like this for Java? I've been combing through the interwebs for a while and trying different solutions but not much is working at this point.

-- Kolton Starr
dockerfile
java
kubernetes
spring
spring-boot

1 Answer

4/10/2020

Loading environment variables requires some configuration, otherwise there won't be anything looking for a db-secret.yaml file.

One approach is to place the configuration values directly into application.properties or application.yml. You will probably also need to make sure that those files are not committed into a repository (.e.g. added to .gitignore).

-- arjay.codes
Source: StackOverflow