11
votes

I am learning how to use Docker with a Spring Boot app. I have run into a small snag and I hope someone can see the issue. My application relies heavily on @Value that are set in environment specific properties files. In my /src/main/resources I have three properties files

  • application.properties
  • application-local.properties
  • application-prod.properties

I normally start my app with: java -jar -Dspring.profiles.active=local build/libs/finance-0.0.1-SNAPSHOT.jar

and that reads the "application-local.properties" and runs properly. However, I am using this src/main/docker/DockerFile:

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD finance-0.0.1-SNAPSHOT.jar finance.jar
RUN sh -c 'touch /finance.jar'
EXPOSE 8081
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /finance.jar" ]

And then I start it as:

docker run -p 8081:80 username/reponame/finance -Dspring.profiles.active=local

I get errors that my @Values are not found: Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.datasource.driverClassName' in value "${spring.datasource.driverClassName}"

However, that value does exist in both *.local & *.prop properties files.

spring.datasource.driverClassName=org.postgresql.Driver

Do I need to do anything special for that to be picked up?

UPDATE:

Based upon feedback from M. Deinum I changing my startup to be:

docker run -p 8081:80 username/reponame/finance -eSPRING_PROFILES_ACTIVE=local

but that didn't work UNTIL I realized order matter, so now running:

docker run -e"SPRING_PROFILES_ACTIVE=test" -p 8081:80 username/reponame/finance

works just fine.

2
Try adding ENV SPRING_PROFILES_ACTIVE=local to your Docker filePär Nilsson
-Dspring.profiles.active will obviously do very little for docker. Instead use -e which is for passing environment variables. Use -e SPRING_PROFILES_ACTIVE=local instead.M. Deinum
M. Deinum, if you will make this an answer I will gladly accept it. Thank you for your help!sonoerin
In my case the problem was with the CMD string in the Dockerfile that launched the application. I was storing the config files outside the standard path (not in the resources folder), so after adding the -Dspring.config.location=/app/conf/ into the launch string the problem was solved. The launch string became this: CMD java -Dspring.config.location=/app/conf/ -jar lib/application.jarkolyaiks

2 Answers

6
votes

You can use docker run Using Spring Profiles. Running your freshly minted Docker image with Spring profiles is as easy as passing an environment variable to the Docker run command

$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker

You can also debug the application in a Docker container. To debug the application JPDA Transport can can be used. So we’ll treat the container like a remote server. To enable this feature pass a java agent settings in JAVA_OPTS variable and map agent’s port to localhost during a container run.

$ docker run -e "JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n" -p 8080:8080 -p 5005:5005 -t springio/gs-spring-boot-docker

Resource Link: Spring Boot with Docker

Using spring profile with docker for nightly and dev build:

Simply set the environment varialbe SPRING_PROFILES_ACTIVE when starting the container. This will switch the active of the Spring Application.

The following two lines will start the latest Planets dev build on port 8081 and the nightly build on port 8080.

docker run -d -p 8080:8080 -e \"SPRING_PROFILES_ACTIVE=nightly\" --name nightly-planets-server planets/server:nightly
docker run -d -p 8081:8080 -e \"SPRING_PROFILES_ACTIVE=dev\" --name dev-planets-server planets/server:latest

This can be done automatically from a CI system. The dev server contains the latest build and nightly will be deployed once a day...

6
votes

There are 3 different ways to do this, as explained here

  1. Passing Spring Profile in Dockerfile
  2. Passing Spring Profile in Docker run command
  3. Passing Spring Profile in DockerCompose

Below an example for a spring boot project dockerfile

<pre>FROM java:8
ADD target/my-api.jar rest-api.jar
RUN bash -c 'touch /pegasus.jar'
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=dev","-jar","/rest-api.jar"]
</pre>

You can use the docker run command

docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=dev" --name rest-api dockerImage:latest

If you intend to use the docker compose you can use something like this

version: "3"
services:
  rest-api:
     image: rest-api:0.0.1
     ports:
       - "8080:8080" 
     environment:
       - "SPRING_PROFILES_ACTIVE=dev"  

More description and examples can be found here