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=localor 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=exampleOr 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.jarNB: 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=exampleNote 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.