Microservice java property not set in application.properties - spring-boot

I have the following line in micros1-mvc microservice application.properties: eureka.client.serviceUrl.defaultZone=${EUREKA_SERVER}
I execute the microservice inside the container with:
sudo docker run -p 8081:8081 --network mynetw --env JAVA_OPTS="-DEUREKA_SERVER=http://eurekaserver:8761/eureka" micros1-mvc
And when the microservice tries to connect with Eureka it says:
overyClient :
DiscoveryClient_SERVICEASERVICE/1754e70517a8:serviceaservice:8081 -
was unable to refresh its cache! This periodic background refresh will
be retried in 30 seconds. status = There is no known eureka server;
cluster server list is empty stacktrace =
com.netflix.discovery.shared.transport.TransportException: There is no
known eureka server; cluster server list is empty at
com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient.execute(RetryableEurekaHttpClient.java:108)
at
com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
at
com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6.execute(EurekaHttpClientDecorator.java:137)
at
com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient.execute(SessionedEurekaHttpClient.java:77)
at
com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator.getApplications(EurekaHttpClientDecorator.java:134)
at
com.netflix.discovery.DiscoveryClient.getAndStoreFullRegistry(DiscoveryClient.java:1101)
at
com.netflix.discovery.DiscoveryClient.fetchRegistry(DiscoveryClient.java:1014)
at
com.netflix.discovery.DiscoveryClient.refreshRegistry(DiscoveryClient.java:1531)
It looks like the microservice properties file doesn't receive the specified value in docker execution

After some searching, I came across the fact that JAVA_OPTS are very specific to Catalina (Tomcat). Looking in the bin folder of a tomcat install you'll find a shell script that handles passing JAVA_OPTS into the exec lines.
A Dockerfile like:
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","${JAVA_OPTS}","-jar","/app.jar"]
With:
docker run -p 9000:9000 -e JAVA_OPTS=-Dserver.port=9000 myorg/myapp
Fails. This fails because the ${} substitution requires a shell. The exec form does not use a shell to launch the process, so the options are not applied. You can get around that by moving the entry point to a script or by explicitly creating a shell in the entry point. The following example shows how to create a shell in the entry point:
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app.jar"]
You can then launch this app by running the following command:
docker run -p 8080:8080 -e "JAVA_OPTS=-Ddebug -Xmx128m" myorg/myapp

Related

Create docker image with named/host volume for spring boot application

I have spring boot application which I am trying to dockerize for the first time. I am using docker version 20.10.1 and my host pc is ubuntu 20.04
for this spring boot application, I have a data directory , which has data created when the application is running. I want to access this data from the host operating system. That is why I am using volume.
When I try to mount my container to named volume or to a host volume, but it always create anonymous volume regardless of the command I type.
Here is my docker file.
FROM openjdk:15
COPY target/lib/* /usr/src/app/lib/
COPY target/core-api-7.3.6.jar /usr/src/app/lib/core-api-7.3.6.jar
COPY config/application.properties /usr/src/app/config/application.properties
COPY data/poscms/config/* /usr/src/app/data/poscms/config/
WORKDIR /usr/src/app
ENTRYPOINT ["java", "-jar", "lib/core-api-7.3.6.jar"]
VOLUME /usr/src/app/data
/usr/src/app/data this is the directory where core-app.jar application will create its runtime data, I need to access these data from my host pc
Following is the command for building the image
docker build -t core-app:5.0 .
then I create image using following command
docker run -it -d -p 7071:7071 core-app:5.0 -v /home/bob/data/:/usr/src/app/data
when I check the volumes by running following command
docker volume ls
I can see anonymous volume being created by this container
and my host path which is /home/kapila/data/ is empty and container data is not written to host path.
I experience the same behaviour with named volume as well.
I created a named volume using following command
docker volume create tmp
docker run -it -d -p 7071:7071 core-app:5.0 -v tmp:/usr/src/app/data
and still docker create anonymous volume and data is not written to tmp volume
my host PC is ubuntu pc. Could someone point out what I am doing wrong here
I do something like this:
In your project root , have these files pertaining to docker as required:
1. DockerFile 2.docker-compose.yml 3. docker-env-preview.env
DockerFile content
FROM openjdk:8-jdk-alpine
ARG jarfilepath
RUN mkdir /src
WORKDIR /src
VOLUME /src/tomcat
ADD $jarfilepath yourprojectname.jar
docker-compose.yml content
version: '3'
services:
project-name:
container_name: project-name-service
build:
context: .
args:
jarfilepath: ./target/project-0.0.1.jar
env_file:
- docker-env-preview.env
ports:
- "8831:8831"
- '5005:5005'
networks:
- projectname_subnet
command: java -jar -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 projectname.jar --spring.profiles.active=preview
networks:
project-name_subnet:
external: true
docker-env-preview.env
This file will contain your environment variables values. The applicaiton.properties can read this file to fetch the values, like buildserver.ip=${BUILD_SERVER_DOMAIN}. Basically you define what you want need . Like the example below.
GARBABE_SERVER_DOMAIN=h-db-preview
GARBABE_SERVER_PORT=5422
GARBABE_DB=projectdb
GARBABE_USER=user
GARBABE_PASSWORD=pwd
JPA_DDL_AUTO=validate
JPA_DIALECT=org.hibernate.dialect.PostgreSQLDialect
JPA_SHOW_SQL=false
JPA_SE_SQL_COMMENTS=true
JPA_FORMAT_SQL=false
JPA_NON_CONTEXTUAL_CREATION=true
APP_NAME=project-name-service
BUILD_SERVER_METHOD=http
BUILD_SERVER_DOMAIN=7.8.9.4
Commands to execute :
mvn clean package (if you use maven )
docker-compose up -d --build ( execute docker ps -> check the details on the running container),
To view the logs : sudo docker logs <project-name-service> -f
To get into the container console, docker exec -it <project-name-service> bash
I was able to fix the issue, and only change I did, to make it work, is that, to change the base image from
FROM openjdk:15
to
FROM adoptopenjdk/openjdk15:ubi
and now named and host volume mounts are working as expected. I am not sure what is wrong with official openjdk:15 image.

unable to run docker container as getting this error:Unable to access jarfile app.jar

I have created the image using below Docker file.Its working fine in local when I run it in the container using this image[docker run -p 80:8080 username/spring-boot-docker-aws-demo:tag
FROM openjdk:8-jdk-alpine
COPY target/spring-boot-docker-aws-demo.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","app.jar"]
I have pushed this image to Docker hub to run it in EC2 instance.when I run it its saying "Error: Unable to access jarfile app.jar"
https://hub.docker.com/layers/chaituu/spring-boot-docker-aws-demo/docker-aws-demo-tag/images/sha256-110363a016eb2250264d96c8890dede518d8e519fdc9a27174334fe1096a540e?context=repo
what could be the issue?
I had a similar issue today (although in my case it wouldn't even run locally). Here's what your Dockerfile would look like with my fix:
FROM openjdk:8-jdk-alpine
COPY target/spring-boot-docker-aws-demo.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["sh"]
CMD ["-c", "java -jar /app/app.jar"]

Docker run with -e not working.Failed to pass spring.profiles.active in the run command

I am facing one issue with my docker file.Image build was successful but while running I am getting an error because the active profile I am setting in the run command is not reflecting.
# Get java
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR
COPY ${JAR} app.jar
EXPOSE 8080
ENV severn_js_key=1234qasw
ENTRYPOINT ["java", "-jar", "app.jar"]
My run command is like
sudo docker run -e SPRING_PROFILES_ACTIVE=dev -p 8088:80 -t tws-apps/service:1.0.0-SNAPSHOT
I am getting a null pointer exception in the server log while executing this statement
String environment = System.getProperty("spring.profiles.active");
switch (environment) {
Please help
You pass the SPRING_PROFILES_ACTIVE to the docker container as a system environment variable. You should pass it as a Java System Property instead. A solution would be to run the container by overriding the entrypoint:
docker run --entrypoint java -t tws-apps/service:1.0.0-SNAPSHOT -Dspring.profiles.active=dev -jar app.jar
In alternative, in your Dockerfile change the entrypoint. It could be a script that reads the SPRING_PROFILES_ACTIVE environment variable and then runs Java with the var as a system property.
Hope it helps.

how to run docker with keycloak image as a daemon in prod environment

I am using docker to run my Keycloak server in aws production environment. The problem is keycloak uses wildfly which is constant running. Because of this I cannot close the shell. I am trying to find a way to run docker as a daemon thread.
The command I use to run docker
docker run -p 8080:8080 jboss/keycloak
Just user docker's detach option -d.
docker run -p 8080:8080 -d jboss/keycloak

Passing env variables to DOCKER Spring Boot

I have a SpringBoot application and its Dockerfile is as follows. I have application.properties for different environments like local/dev/qa/prod. When I run the application locally in IDE, I pass -Dspring.profiles.active=local in VM options so that it loads the application-local.properties. For running as docker containers, I build an image which comprises of all the application.properties. i.e. it's only SAME docker image for all the environments.
When I run the image in an environment, I want to somehow make the SpringBoot to understand that its dev env, so it has to load application-dev.properties. I am using AWS ECS for managing the containers.
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/sample-test-sb-sample-app-1.0-exec.jar app.jar
EXPOSE 8080
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
The easiest (and probably the best way) to do it via environment variable in a docker container:
SPRING_PROFILES_ACTIVE=dev,swagger
UPDATE:
In order to set environment variables to docker, you do not need to modify Dockerfile. Just build your docker image and then run it with the env variables set:
docker run your-docker-container -e SPRING_PROFILES_ACTIVE='dev,swagger' -p 8080:8080
In the .Dockerfile file:
ENTRYPOINT [ "sh", "-c", "java -Dspring.profiles.active=**${ENV}** -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
And while running the docker:
docker run --env ENV=*local* -d -p 8080:8080 <*image id*>
This way, the environment variable gets local as value and passes to Dockerfile when we bring up a container.
Update
You can also do like
ENTRYPOINT ["java","-jar", "-Dspring.profiles.active=${ENV} -Djava.security.egd=file:/dev/./urandom","app.jar"]
and while docker image
docker run --env ENV=local -d -p 8080:8080 <*image id*>

Resources