title: "Secrets and properties management"
date: 2019-10-17T20:53:32-04:00
draft: false
Secrets and properties management
Properties files with Spring boot
Specify different profiles (for the different DB for example) like this in the default application.properties file:
spring.profiles.active=local
or at runtime like that:
java -Dspring.profiles.active=local -jar yourApplication.jar
please note the -D params are set BEFORE the -jar
It will automatically take the corresponding properties file in the classpath application-local.propertie
Secrets with Spring boot
When you have to specify a secret, just define a placeholder instead:
spring.datasource.password=${db-password}
and pass the value at runtime with a Java -D variable:
-Ddb-password=example
Or you can also externalize your config folder or just a properties file:
Spring Properties File Outside jar
and also pass the locations at runtime with an environment variable or just a java -D variable.
Environment and Java variables
Problem is how to pass the environment variables or the java -D variables when your jar is embeded inside a docker image ?
Dockerfile
#https://docs.docker.com/engine/reference/builder/#using-arg-variables
FROM openjdk:8-jdk-alpine
ARG JAR_FILE
ADD ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=${PROFILE}", "/app.jar"]
${PROFILE}
is referencing an environment variable that will be resolved at the runtime only, not during the build time.
${JAR_FILE}
is referencing an argument passed within the docker build command (launched from docker-compose or maven). This variable is not used anymore after the build is done.
more info on the env variables here
Docker-compose
app:
image: "dakarinternational/dakar:latest"
env_file: .env
build:
dockerfile: Dockerfile
context: .
args:
JAR_FILE: $JAR_FILE
ports:
- "8080:8080"
container_name: 'app-dakar'
depends_on:
- "couch"
Here is the .env file:
PROFILE=prod
JAR_FILE=target/dakar-0.0.3.jar
NB: Please note that the JAR_FILE could (and should) be put directly in the args section.
No need for such an environment variable just for the build time, it's here just to demonstrate how we can use env variables within the docker-compose file.
Another way to do the same thing is like this:
app:
image: "danslarue/homeless:latest"
build: .
ports:
- "9090:8080"
container_name: 'app-homeless'
environment:
- db-password=example
Note the environment part
Maven
Here is the config for the docker plugin:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.10</version>
<configuration>
<!--<serverId>docker-hub</serverId>-->
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
<!--<registryUrl>https://index.docker.io/v1/</registryUrl>-->
<repository>dakarinternational/dakar</repository>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
Notice the <JAR_FILE>
build argument.
CircleCI
If you don't want to use Docker-compose environment variables, then you can also pass directly circleci secret environment variable like this:
- run:
name: java command
command: |
java -Ddb-password=$DB_PWD -jar blabla.jar
Notice the $DB_PWD
circleci secret environment variable
Vault by HashiCorp
Another solution to avoid all these variables transmissions is to use Vault.