I have a very simple java jar application that fetches DB properties from the env variables.
I`ve dockerized it and migrated to Kubernetes. I also created a config map and secret with parameters to my DB - so I have access to these properties in the container.
Is it possible to fetch all properties and inject it in Dockerfile? How can I do it?
FROM openjdk:8-jre
ADD target/shopfront-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8010
ENTRYPOINT ["java","-Ddb.host=**value-from-env-variable**","-jar","/app.jar"]
You can use them like this
ENTRYPOINT ["java", "-jar", "-Ddb.host=${DB_HOST}", "/app.jar"]
where DB_HOST should be defined in config map you have created.
I have tried this in my Spring Boot Application for setting Spring Profile.
The array or "exec form" of entrypoint uses exec to run the specified binary rather than a shell. Without a shell the string $DB_HOST is passed to your program as argument.
Shell form
ENTRYPOINT java -Ddb.host="${DB_HOST}" -jar /app.jar
Shell script
If your startup get more complex you can also use an ENTRYPOINT script.
ENTRYPOINT ["/launch.sh"]
Then launch.sh contains:
#!/bin/sh -uex
java -Ddb.host="${DB_HOST}" -jar /app.jar
As I understand you need to fetch parameters from config map and secret and set them as environment variables in your container. Furtunately it's quite nicely described in Kubernetes documentation.
Have a look at below links:
How to use secret: https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables
How to use config map: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#use-configmap-defined-environment-variables-in-pod-commands
To sum up, such resources need to be just defined in Pod's configuration.
Related
I have a spring boot application that is dockerized. By default the application has spring.cloud.config.enabled=false hence the application doesn't pick up the application.properties from configserver. However while deploying in a separate env we need to integrate the application with configserver so we need to override and set the spring.cloud.config.enabled property to true.
To achieve this I am running the docker image using the following docker-compose file :
version: '3'
services:
my-app-new:
container_name: my-app
image: my-app:1.0.0-SNAPSHOT
ports:
- "8070:8070"
environment:
- SPRING_CLOUD_CONFIG_ENABLED=true
- SPRING_CLOUD_CONFIG_URI=http://localhost:14180
However, it just doesn't work. If I hard code the values in the property file then it integrates fine.
I also tried the following command but it still didn't work :
docker run -p 8070:8070 -e SPRING_CLOUD_CONFIG_ENABLED=true -e SPRING_CLOUD_CONFIG_URI=http://localhost:14180 my-app:1.0.0-SNAPSHOT
The spring boot version is 2.2.6.
Let me know what the problem is.
Update :
I cannot use profiles as there too many env in our company and even the VMs keep getting changed so cannot have hardcoded profiles. We want a solution where we can just pass certain variables from the outside.
As someone pointed out in the comments the above compose yml is not working as the environment variables need to read by the spring boot application. So did some research on the internet and instead we are now passing the JAVA_OPTS tomcat variable while running the image. Like so :
docker run --env JAVA_OPTS="-Dspring.cloud.config.uri=http://localhost:14180 -Dspring.cloud.config.enabled=true" -p 8080:8080 my-app-image
And in the docker file we have used the JAVA_OPTS while starting the jar like so
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar" ]
And this still doesnt work. Not sure what is going wrong.
I found the problem with my setup. I made a silly error. The config server is not in my docker network and I used localhost to communicate with the config server. Localhost would of course mean that I am referring to the app containers IP which only has the app running. Instead when I used the ip address or the hostname of my machine my application container could connect to the config server successfully.
Why you not run container --> go inside --> change configuration and commit to new images.
After that deploy to new env.
Good day everyone.
I have a simple java-based cucumber application, that runs in Docker. I planing to specify which scenarios to run by using ENV for Cucumber tags.
My Dockerfile that able to run specified tags:
FROM maven:3.6.1-jdk-11
COPY target/cucumber-app.jar ./
CMD java -jar -Dcucumber.options='--tags #default' cucumber-app.jar
In this case, during docker run command all works perfectly.
I plan to set up a default scenario for not specified Tags and ability to set up special scenarios through ENV:
FROM maven:3.6.1-jdk-11
COPY target/cucumber-app.jar ./
ENV TAG '--tags #default'
CMD java -jar -Dcucumber.options=$TAG cucumber-app.jar
Unfortunately in this case after running docker container I got:
Error: could not open `default'
Possible you have any ideas why using ENV crash possibility to specify cucumber.options?
If you have a recent version of Cucumber rather then trying to squeeze command line options in through a system property via an environment variable, you can set the environment variable straight away. I.e:
ENV CUCUMBER_FILTER_TAGS '#Cucumber and not (#Gherkin or #Zucchini)'
CMD java -jar cucumber-app.jar
https://github.com/cucumber/cucumber-jvm/tree/main/core
I was deploying my Spring Boot Application on AWS Elastic Beanstalk. My web app is using Jasypt, so in the application.properties file, I wrote down jasypt.encryptor.password=, currently the password in this file is empty, I want to pass the password as a variable on AWS Beanstalk's configuration.
When testing locally, I used java -jar myapp.jar --jasypt.encryptor.password=1234 in command line, and it ran successfully. However, when deploying on AWS, I added jasypt.encryptor.password in environment properties and set its value to 1234, the app failed to run. The log said I cannot set the password as empty. So, at this point Beanstalk did not read the environment property I just set. But it can really read the properties later because I tested it after setting another property and used GET API to print it.
My question is: how to make Elastic Beanstalk run/read the environment properties at the beginning? In other words, how to make EB run java -jar myapp.jar with --jasypt.encryptor.password=1234attached?
Thank you so much in advance!
Procfile can't use environment variables. Use a shell script to start the application instead of invoking java -jar directly in Procfile.
Procfile:
web: /bin/sh start_server.sh
start_server.sh
#!/bin/bash
JAVA_OPTS='-Djasypt.encryptor.password=1234'
exec java $JAVA_OPTS -jar myapp.jar
references: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/platforms-linux-extend.html
I am wondering if is possible to do the following...
I have a small application in java (and gradle)
I am trying to set it in a container, so I created the Dockerfile and worked fine UNTIL I have to set a parameter.
To run it locally on my IDLE I set these program arguments:
server application-local.yml
That actually loads a file with many properties, without this the app will fail.
On my Dockerfile I have this
FROM openjdk:8-jdk-alpine
USER root:root
ENV NAME test
LABEL maintainer="myself"
WORKDIR /opt/apps
COPY build/libs/myapp.jar /opt/apps/myapp.jar
EXPOSE 8080
CMD ["java", "myapp.jar"]
I was wondering if I could do the following:
CMD ["java", "-server:application-local.yml", "myapp.jar"]
but doesnt work, also I cannot do
java -jar myapp.jar -server:application-local.yml
simply doesnt do anything
Dont wanna do a gradleBuild because it is supposed to use java only at my docker image...
Any idea how to do this?
Edit:
So, I have done the following, move my application-local.yml to a folder I can copy and added this
COPY some-path/application-local.yml /opt/apps/local.yml
and moved the CMD for this
CMD ["java", "myapp.jar", "server", "local.yml"]
I still get the same error, basically cannot resolve the values from that yml file.
EDIT 2 ---
Basically what I cannot do is to figure out how to send the application.default.yml as configuration file, I realise also that the -server does not anything, is my config file the one I cannot load and is not present in the jar (normal behaviour)
When using the java command, order of the arguments matter
First you put the java options, like -server, then the -jar ... Or the class name in the case of running classes directly, and then the application arguments
The proper way to run your app is:
CMD ["java", "-jar", "myapp.jar", "server", "application-local.yml"]
Then you have another problem, you are only copying the final jar file to your docker container, so it can can't find the application-local.yml file, copy this also to your docker container
COPY build/libs/application-local.yml /opt/apps/application-local.yml
I want to run my spring-boot application with a certain profile. Therefore, I need to pass the -Dspring.profiles.active=dev argument to the JVM.
My dockerfile looks like this:
FROM tomcat:9.0.10-jre8
EXPOSE 8080
ENV JAVA_OPTS="-Dspring.profiles.active=dev"
COPY myapp.war /usr/local/tomcat/webapps/myapp.war
The application starts but the JVM option with the profile name does not seem to be set.
What am I missing?
Just simply add this in your Dockerfile :-
ENV spring.profiles.active=dev
and other option is below, by adding one ENTRYPOINT:-
ENTRYPOINT ["java","-Dspring.profiles.active=container","-jar","/app.jar"]