How to load custom xml files during docker run? - java

I have a two custom xml property files that are environment specific used in my spring boot project. Is it possible to use mount or volume tag to get the files from a location specified during docker run? The xml files are required to successfully connect to a db server.
Also if I specify an env-file command in the docker run can i put my sh files in any location on the docker server and specify the path there in the run command?

Yes, you can do that by mounting a volume. It will swap your in-container location with chosen server location. Inside container there will be no difference between this shared location and any other. Use flag -v "SERVER_LOCATION:CONTAINER_LOCATION":
docker run -v /etc/xmlsFolder:/etc/appConfig/destinationFolder your_image
Yes, you can specify run command in script anywhere on server.

Related

Docker container not printing logs not location specified in log4j2.xml

I have configured a Docker Image for my Spring boot application. I have also configured logs using log4j.xml. But, on running the docker image, the logs are getting printed neither in the docker logs nor on the location specified in log4j.xml.
Below is my Dockerfile
FROM openjdk:8
ADD <relative path to jar>/jar-name.jar jar-name.jar
ADD <relative path to property file>/application.properties /app/application.properties
ADD <relative path to log4j file>/log4j2-8081.xml /logs/log4j2-8081.xml
ENV JAVA_OPTS="8080"
ENTRYPOINT ["java", "-Dapp.home=classpath:file:/app/", "-
Dlog4j.configurationFile=classpath:file:/logs/log4j2-8081.xml", "-jar", "jar-name.jar"]
I need to pass the log4j.xml file path during the execution of the docker run command.
Thanks in advance
Docker Run Command:-
docker run -p 8081:8081 -e JAVA_OPTS=-Dserver.port=8081 rdsstg
So per your query you are saying the logs aren't getting printed per the log4j config in application code and in your docker container, kindly correct my inference. Thanks.
Now per your comment,
I want to create logs outside the container. In the location /log of the system.
The answer is to use volumes, where-in the path of host machine and docker container is provided. The bare minimal usage is to use -v option See below. For deep dive please refer Use volumes for more details.
docker run -p 8081:8081 -e JAVA_OPTS=-Dserver.port=8081 -v /host_machine/log:/container/var/app/log rdsstg
BUT, you do need to understand in order for your docker container to direct log files(or any files per say) on host machine, those files should be generated in container i.e app logging should be working in container. This is your #1
Let me know if above make sense.
On a side note
for -e usage, I would recommend to use the --env-file option so that you can keep multiple env variables in one file instead of passing multiple -e.
It would have been difficult to explain in comments section.

how to parse a file from a java docker container application

I have a java application which needs to parse a data set file. I have containerized the app using docker but the container does not see my file in my host.
So, I need to somehow include it inside the docker container or make it available through a docker volume which is mapped into my container.
inside the java app I have
String dataSet = "/usr/DataSet/TempData.txt"; // inside the container
File textfile = new File(dataSet);
Scanner sc = new Scanner(textfile);
and my file is stored in a directory (/home/myusername/Desktop/DataSet) in my host.
I compile and build my docker image using spotify plugin in maven.
After I build the image, I run a container and map a volume that contains my TempData.txt:
sudo docker run -it -v /home/myUserName/Desktop/DataSet:/usr/DataSet --name myapp myImageName bash
But I get java.io.FileNotFoundException error because the file is not available in my container ..
what is the best way to make a file available to my java dockerized app to be able to read and parse it ?
Thanks for your inputs!
The problem was solved when I put my file in my home directory. and then mapped it into my container ...

Read local file system with Java from Docker container

I have a java app running on a docker container on mac osx. I want to access a file on a certain directory within the local file system using Paths.get('/Users/username/folder')
I am getting errors because docker is reading from its vm directory. How will I within a java app access the local file system while running the app in docker?
You can share the folder in the host machine with the container:
docker run -v your/host/folder:/your/container/folder ....
And then you can use Paths.get('/your/container/folder')
If you map the host folder in the same folder inside the container then you don't have to take care about it in the java code docker run -v your/folder:/your/folder ..... You also have to keep in mind issues with permissions...
Official documentation

Vert.x based application crashes on docker container

I'm trying to run a Vert.x Java based application on a Docker container. My application runs few verticles which it initiates from within itself.
I've put the jar file on a folder and created a Dockerfile with the following content:
FROM vertx/vertx3
ENV VERTICLE_FILE Medical-1.0-SNAPSHOT.jar
ENV VERTICLE_HOME /performit/web/vertx/verticles/
COPY $VERTICLE_FILE $VERTICLE_HOME/
WORKDIR $VERTICLE_HOME
ENTRYPOINT ["sh", "-c"]
EXPOSE 8080
CMD ["java -jar $VERTICLE_FILE"]
USER daemon
I create an image with the command
$ sudo docker build -t medical-main .
I then attempt to create a container with the following line:
sudo docker run --name medical-main -p 8080:8080 -d medical-main
This fails and the log shows the following:
java.lang.IllegalStateException: Failed to create cache dir
at io.vertx.core.impl.FileResolver.setupCacheDir(FileResolver.java:257)
at io.vertx.core.impl.FileResolver.<init>(FileResolver.java:79)
at io.vertx.core.impl.VertxImpl.<init>(VertxImpl.java:138)
at io.vertx.core.impl.VertxImpl.<init>(VertxImpl.java:114)
at io.vertx.core.impl.VertxImpl.<init>(VertxImpl.java:110)
at io.vertx.core.impl.VertxFactoryImpl.vertx(VertxFactoryImpl.java:34)
at io.vertx.core.Vertx.vertx(Vertx.java:79)
What am I missing?
Izhar
Judging by FileResolver.java, vert.x tries to create a ".vertx" directory in the current working directory by default. You have configured a user called "daemon", are you sure that this user has write access to the working dir in the docker image? If not, change the permissions as outlined in docker-image-author-guidance, or revert to using the root user.
This directory is used to serve files contained in jar files (for example web assets packaged in a fat jar). If you are not using this feature, you can disable the creation of this directory by setting the vertx.disableFileCPResolving system property to true. You can also change the location using the vertx.cacheDirBase system property.
Reference:
https://groups.google.com/forum/#!topic/vertx/7cBbKrjYfeI
This exception is caused when Vert.x tries to create .vertx (cache dir) so that it can copy and read a file from the classpath or file that's on the classpath. It's possible, the $user doesn't have permission to create the cache directory.
The reason behind cache dir is simple: reading a file from a jar or from an input stream is blocking. So to avoid to pay the price every time, Vert.x copies the file to its cache directory and reads it from there every subsequent read. This behavior can be configured.
vertx run my.Verticle -Dvertx.cacheDirBase=/tmp/vertx-cache
# or
java -jar my-fat.jar -Dvertx.cacheDirBase=/tmp/vertx-cache
Otherwise, you can completely avoid this behavior, launch your application with -Dvertx.disableFileCaching=true. With this setting, Vert.x still uses the cache, but always refresh the version stored in the cache with the original source. So if you edit a file served from the classpath and refresh your browser, Vert.x reads it from the classpath, copies it to the cache directory and serves it from there. Do not use this setting in production, it can kill your performances.
link to documentation
For me, this same issue was coming for while trying to run a jar file. It started coming suddenly and then I was forced to run the jar file as ROOT for sometime until I finally got fed up and started looking for reason thoroughly.
It happened because I accidentally ran jar file once in SUDO
privileges and the .vertx folder was create as ROOT account.
I could not figure this out initially as I was trying ll alias
command in amazon linux and sadly it does not display hidden folders
So when I was thoroughly investigating the issue next time, I also tried ls -al which showed in .vertx folder and I figured out that issue was it being created as SUDO user.
Deleted .vertx folder and jar file started working normally again as
normal user.
vert.x tries to create a cache-dir (.vertx/file-cache-someuuid) in the current directory. The given exception will be thrown if the mkdirs() call fails.
Has the user daemon sufficient rights in the workdir?

Spring Boot External Configuration when using Docker

I'm developing a Spring Boot application which I'd like to deploy with Docker.
The trouble I'm having is we need to store the properties file on the server, similar to how Tomcat allows you to put the properties file in /lib.
How would I go about getting Spring Boot to use this file when running inside Docker?
Docker provides a way to do this using Volumes:
In addition to creating a volume using the -v flag you can also mount a directory from your own host into a container.
$ sudo docker run -d -P --name yourapp -v /lib:/lib yourcontainer/name
So in your containerized app, you would just look in /lib (or wherever you find convenient to mount it), and when you book the container, you specify the host directory you want mounted.
Another option I've used is to create a container with just the configuration (use busybox or something small) and then export a directory from within that as a volume that you share in other containers. This does set up a dependency between containers that you have to manage, but it gives you the benefit of being able to version your configuration and not have to have it just sitting on the host file system.
Both of these strategies are discussed at the link above.
You can also override application.properties file directly:
docker run -v custom.properties:/data/application.properties spring-boot-app

Categories

Resources