passing command line parameters to spring boot services inside docker container - spring

I have got a set of spring boot apps that I would like to package as docker containers.
I am using the following Dockerfile to create the container for one of the services:
FROM java:8
VOLUME /tmp
ADD myservice.jar app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
Inside, the services access some environment properties like for instance:
#Value("${my.test.param:default}")
String testParam;
.
.
.
logger.info("param value is = "+testParam);
Now, I would like to be able to override this setting via docker run command line like this
docker run -p 8080:8080 -e my.test.param=changed mygroup/myservice:0.0.1
Unfortunately, this doesn't seem to work. I keep seeing the default value for the parameter my.test.param.
I searched for ways to automatically add all -e parameters at the end of the ENTRYPOINT line, but didn't find any. Is there some general solution for this?

Related

How to Pass environment as argument for a spring boot docker image?

I created a docker file like this
ARG ENV
FROM openjdk:11-jdk
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","-Dspring.profiles.active=${ENV}", "app.jar"]
while doing
docker run -p 8100:8080 anupbiswas1984/docker-env --e ENV=test
it is not identifying ${ENV}
How can I pass the ENV as an argument during "docker run..."
Get rid of the ARG thing, as it's not needed and you aren't using it correctly anyway. Per the documentation:
The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command
So ARG is a build-time thing, and you are trying to use it as a run-time environment variable.
Also, you can get rid of the "-Dspring.profiles.active=${ENV}" part of your ENTRYPOINT because Spring Boot already looks for an environment variable named SPRING_PROFILES_ACTIVE so there's no need to define another thing here, and you're also introducing an issue with the way you are trying to resolve the ENV variable here.
FROM openjdk:11-jdk
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]
Then run it with:
docker run -e SPRING_PROFILES_ACTIVE=test -p 8100:8080 anupbiswas1984/docker-env

Cannot access environment variables in Docker environment

I am trying to dockerize my spring boot project and use it in EC2 instance.
In application.properties I have following lines,
spring.datasource.url=${SPRING_DATASOURCE_URL}
spring.datasource.username=${SPRING_DATASOURCE_USERNAME}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD}
and I am reading SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME and SPRING_DATASOURCE_PASSWORD from my environment.
I have following Dockerfile,
FROM openjdk:latest
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar", "-DSPRING_DATASOURCE_URL=${DATASOURCE_URL}", \
"-DSPRING_DATASOURCE_USERNAME=${DATASOURCE_USERNAME}", \
"-DSPRING_DATASOURCE_PASSWORD=${DATASOURCE_PASSWORD}", "/app.jar"]
EXPOSE 8080
When I try to run run the following command,
sudo docker run -p 80:8080 <image-repo> --env DATASOURCE_URL=<url> --env DATASOURCE_USERNAME=<username> --env DATASOURCE_PASSWORD=<password>
My application crashes because of the non-existing environment variables.
Also,
I have tried using docker-compose mentioned Spring boot app started in docker can not access environment variables link. It become much more complicated for me to debug.
TL;DR I want to achieve information hiding in my spring boot application. I want to use environment variables to hide my credentials to the database. However, my dockerized program is not having the environment variables that I want to have.
If you have any approaches other than this, I would be also happy to listen the way I can achieve information hiding. Thanks.
You need to put options like docker run --env before the image name. If they're after the image name, Docker interprets them as the command to run; with the specific setup you have here, you'll see them as the arguments to your main() function.
sudo docker run \
--env SPRING_DATASOURCE_URL=... \
image-name
# additional arguments here visible to main() function
I've spelled out SPRING_DATASOURCE_URL here. Spring already knows how to map environment variables to system properties. This means you can delete the lines from your application.properties file and the java -D options, so long as you do spell out the full Spring property name in the environment variable name.

Accessing persistent H2 DB in docker container

I'm deploying a springboot application and I want to use a persistent DB. So, in application.properties file, I have
spring.datasource.url=jdbc:h2:file:/home/ubuntu/db;AUTO_SERVER=TRUE;
Now this works as long as I start this application without using a container. Now, I build a docker image and try to run the application. Dockerfile looks like
FROM maven:3-jdk-11 AS maven
ARG BUILD = target/build.jar
COPY ${BUILD} build.jar
EXPOSE 8080
USER spring:spring
ENTRYPOINT["java","-jar","/build.jar"]
Now this doesn't work when I try to start it, because it searches for /home/ubuntu/db inside the container, which does not exist. Is there a way to make the app inside the docker container access the host folder /home/ubuntu/db? Thanks for the response.
The missing part is to tell docker when running the containter to mount /home/ubuntu/db from the host into the container.
You do that like this:
docker run -v <folder_on_host>:<folder_in_cointainer>
with your example:
docker run -v /home/ubuntu/db:/home/ubuntu/db
more info on docker docs: https://docs.docker.com/get-started/06_bind_mounts/
Just in case it is helpful to anyone else, the full command to be used is:
docker run -v /home/ubuntu/db:/home/ubuntu/db --privileged -p $HOST_PORT:$CONTAINER_PORT <image-name>

How to specify an alternative main class in spring boot using bootBuildImage and packeto

When calling the spring boot plugin bootBuildImage task in gradle, a docker image is created using packeto. It starts the main class specified in the springBoot plugin. Below you can find an excerpt of the build.gradle file.
springBoot {
mainClass = 'MyMainApp'
}
bootBuildImage {
imageName = "$docker_repo/${project.name}"
}
When calling docker run, docker will run a container starting MyMainApp.
However, I want to run an alternative main class, using the same docker image. I tried the following:
specifying -Dloader.main=MyOtherApp as the cmd in docker run
specifying -Dloader.main=MyOtherApp in the JAVA_TOOL_OPTIONS environment variable
specifying LOADER_MAIN=MyOtherApp as an environment variable
None of those options start MyOtherApp.
An image created by Buildpacks provides some helpful tools for launching your application. While this is nice, overriding the default start command isn't as easy as just specifying a new command to docker run.
All of the facilities provided by Buildpacks for starting up various processes in an image are described in the docs.
I'm guessing here a bit, but it sounds like you want to run your own custom process (not the process detected by the buildpack), so try this one here.
You can even override the buildpack-defined process types:
docker run --rm --entrypoint launcher -it multi-process-app bash
docker run --rm --entrypoint launcher -it multi-process-app echo hello "$WORLD" # $WORLD is evaluated on the host machine
docker run --rm --entrypoint launcher -it multi-process-app echo hello '$WORLD' # $WORLD is evaluated in the container after profile scripts are sourced
Java should be on the path, so you can run java -Dloader.main=MyOtherApp org.springframework.boot.loader.PropertiesLauncher.
https://www.baeldung.com/spring-boot-main-class#using-cli
Alternatively, you could change your app to use PropetiesLoader by default & rebuild your image. The buildpack is just pulling the launcher for the start command out of the MANIFEST.MF file. You need to use PropertiesLauncher though as that is what supports loader.main. See https://stackoverflow.com/a/66367534/1585136.

COPY target/test-0.0.1-SNAPSHOT.jar /test.jar COPY failed cannot find file Docker

I'm trying Docker for the first time in a Spring Boot project and I'm trying to make the command docker build -t javademo:v1.3 . work. I don't know where the jar file is, in the Dockerfile I've specified this:
FROM openjdk:8-windowsservercore
LABEL maintainer="Marina"
COPY target/test-0.0.1-SNAPSHOT.jar /test.jar
EXPOSE 8080:8080
CMD ["java", "-jar", "test.jar"]
Because my project name is "test". The problem is that I can't find the test.jar, even if I Maven-build the project. How is this supposed to work? What am I missing?

Resources