Im Developing a simple docker file for a spring boot war file.
FROM openjdk:8-jdk-alpine
ARG CONFIG_LOC=/app_config
RUN mkdir $CONFIG_LOC
COPY app_config/* $CONFIG_LOC/
ARG JAR_FILE=target/*.war
COPY ${JAR_FILE} app.war
ENTRYPOINT ["java","-Dspring.config.location=/app_config","-Dspring.profiles.active=docker","-jar","/app.war"]
Some how the argument config location is not are not loading when running the spring application. So the spring application is not running.
Is there a reason to use these as arguments? Usually using something like ARG CONFIG_LOC means you're passing a value in your build command using --build-arg. Seems like in this build you should just use hard coded values. When running the application, any argument should be passed as an environment variable using the -e flag.
Related
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
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.
This question already has answers here:
Externalising Spring Boot properties when deploying to Docker
(6 answers)
Closed 3 years ago.
How can we provide application.properties to spring boot app in a docker? Would normally copying the application.properties to the container work?
you can keep that file at some location and map that location to volume. It will connect the local machine to docker container's world
Refer this
I suggest you build the Image with properties included. If needed, add a startscript and provide environment variables per stage (dev, qa, prod), which symlink the needed files.
The answer to this will be widely opinionated, some folks like to mount the file as a volume while other like to substitute the required configuration by reading it from environment variables through a shell script that is run as the entrypoint of the docker container.
Although if you're using Spring, it allows externalized configuration which can be taken from multiple sources. One of the sources is the environment variables that directly override the default configuration.
The approach I take though is to provide them as command line arguments to the JVM command by making the JVM command the entrypoint and providing the arguments at the end of the docker run command
In my use case I would like to have two jar files in the containers. In typical docker image, I see an entry point, which basically starts the jar file. In my case, I will not know which program to be started, till the time the container is getting used in the K8s services. In my example, I have a jar file that applies the DDLs and the second Jar file is my application. I want the k8s to deploy my DDL application first and upon completion it will deploy my spring boot application (from a different jar but from same container ) next. There by I cannot give an entry point for my container, rather I need to run the specific jar file using command and argument from my yaml file. In all the examples I have come across, I see an entry point being used to start my java process.
The difference here from the post referred here is- i want to have the container to have two jar files and when I load the container through k8s, I want to decide which program to run from command prompt. One option I am exploring is to have a parametrized shell script, so I can pass the jar name as parameter and the shell will run java -jar . I will update here once I find something
solution update
Add two jars in the docker file and have a shell script that uses parameter. Use the below sample to invoke the right jar file form the K8s yaml file
spec: containers:
- image: URL
imagePullPolicy: Always name: image-name
command: ["/bin/sh"]
args: ["-c", "/home/md/javaCommand.sh jarName.jar"]
ports: - containerPort: 8080
name: http
A docker image doesn't have to run a java jar when starting, it has to run something.
You can simply make this something a bash script that will make these decisions and start the jar you like
Try to add the per-requisites in the Init Containers while deploying it to kubernetes and in the regular container you can place your application, it will make DDLs container to be initialized first and then the following application container can be executed.
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?