I switched from distroless/java:8 to distroless/java:8-debug container and, when deployed to kubernetes, I started getting following error:
Error: Unable to access jarfile /MyApp-0.1.jar
This is my Dockerfile:
FROM gcr.io/distroless/java:8-debug
LABEL CONTAINER_NAME=my-api
ARG JAR_FILE=MyApp/core/build/libs/core-0.1-boot.jar
COPY ${JAR_FILE} MyApp-0.1.jar
ENTRYPOINT ["java","-jar","/MyApp-0.1.jar"]
While I was using regular distroless (everything else was the same) I didn't have this problem.
What is interesting is that when I try to run this Dockerfile locally, I don't get this error. Is this some permission issue?
I redeployed and it is working now. The only logical explanation is that I tried to use nonroot one first and when I switched to root one, some of the pods with nonroot were still there causing the problem.
From what I gathered from this build script:
https://github.com/GoogleContainerTools/distroless/blob/main/java/BUILD
Both of those containers are identical. only the debug one includes java compiler
Also, you could try running the app from the container itself. Run something similar to this:
docker run -it --entrypoint sh my-api
running the whoami inside the container verifies that the user is root, so no restrictions should exist
Related
I want to build an application. For testing it uses testcontainers. The build will run on CI and on the developers' machines. The Dockerfile is more or less:
FROM amazoncorretto:17-alpine as builder
add . .
run ./gradlew build
from amazoncorretto:17-alpine
copy --from=builder build/libs/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
And I run the build using docker build .
Part of the ./gradlew build runs tests with Testscontainers and uses
val sftpDocker = GenericContainer(DockerImageName.parse("atmoz/sftp:alpine"))
And it returns
java.lang.IllegalStateException: Could not find a valid Docker environment. Please see logs and check configuration
I know that:
Testcontainers has its own docker API client and doesn't requires installed docker inside the Alpine container 3
Someone made it using "docker:20.10.14-dind" image. But I don't know how it fits in my problem 4
I can mount the /var/run/docker.sock during docker run ... but I'm using RUN command inside dockerfile and docker build ... instead
I can expose DOCKER_HOST and testcontainers should use the default gateway's IP address. But it's way less secure than using socket
So is there a way to use a socket in this setup? If not, how should I run my host Docker to expose TCP instead of a socket?
I want to Dockerize a web application, which works perfectly fine locally. When trying to run the application inside Docker, an UnsatisfiedLinkError is thrown when invoking a function from the Nauty library.
To work with this library locally, the Spring application has to be started by doing
java -Djava.library.path="<PATH>/backend/lib/" -jar backend.jar
This library path points to the directory where the Nauty library (libnauty.so) resides. In my ~/.bashrc, I also had to set the environment variable LD_LIBRARY_PATH=<PATH>/backend/lib/:/usr/local/lib. After making these two changes, the application works fine and functions from the Nauty library can be invoked without any problems.
After Dockerizing the application, I get the following error when invoking a library function
java.lang.UnsatisfiedLinkError: no nauty in java.library.path: "/home/backend/lib/"
However, the libnauty.so file is copied to the Docker container and is present in /home/backend/lib directory. I also set the environment variable LD_LIBRARY_PATH in the Docker container. The issue however still remains.
I use docker-compose to set up the application. The Dockerfile for the back-end looks like this.
FROM openjdk:17-oracle
ARG JAR_FILE=target/*.jar
EXPOSE 8080
ENV LD_LIBRARY_PATH=/home/backend/lib/:/usr/local/lib
COPY ${JAR_FILE} /home/backend/backend.jar
COPY . /home/backend
ENTRYPOINT ["java", "-Djava.library.path=\"/home/backend/lib/\"", "-jar", "/home/backend/backend.jar"]
Any pointers to how this issue could be solved would be greatly appreciated. I have looked around for quite some time now, but I can't seem to fix the problem.
After hours of googling and debugging, the problem was the double quotes around the library path in the ENTRYPOINT. The correct way to specify it is just
ENTRYPOINT ["java", "-Djava.library.path=/home/backend/lib/", "-jar", "/home/backend/backend.jar"]
Summary:
I have pulled a Tomcat image, and managed to add a .war file to its usr/local/webapps directory. This new entity is a container, and when I run it locally, it works famously on localhost. I am able to see the .war in the webapps directory.
I want to make this a stand-alone, deplyoment ready entity, which, I gather, means I need to turn it into an image in its own right, so I do this:
docker commit theContainer newImage to make new image.
docker run -p 8080:8080 newImage to run new image.
lsof -i :8080 to verify port mapping.
...and see that indeed there is a process listening on the port. So far so good.
Next, I want to verify that newImage contains the .war file, so, with it running, I run:
docker exec -it newImage /bin/bash
cd webapps
ls
...and am happy to find that I can see and navigate the file system of newImage. Unfortunately, usr/local/webapps is empty.
And of course, opening localhost:8080 (and trying all expected servlets) in a browser yields
HTTP Status 404 – Not Found The origin server did not find a current representation for the target resource or is not willing to
disclose that one exists.
So the newImage runs but the app is missing. I have done this, stubbornly, a dozen times, checking all the steps along the way, with no improvement. Clearly I am missing some key information.
I also, after much searching, cooked up a Dockerfile and docker-compose.yml file as follows:
FROM tomcat:latest
ADD target/theApp-1.0-SNAPSHOT.war /usr/local/tomcat/webapps/
EXPOSE 8080
CMD ["catalina.sh", "run"]
version: '3'
services:
app:
build: .
image: newImage
ports:
- 8080:8080
Again, when I run newImage locally it works a treat, but when I try to push it to Docker Hub, and then pull it to test it, if fails and lo, it is lacking the .war file that was copied into it.
Am therefore seeking (and thanking in advance for) any insight into the esoterica of docker and the nature of my ignorance.
It currently makes no sense to me that I can successfully modify an image but on running docker commit the mod is lost. Somewhere I read that commit does not persist data but I'm not sure that applies to a .war file.
Docker Version: 19.03.12
OS: macOS HighSierra 10:13:6
Project: https://www.jetbrains.com/help/idea/deploying-a-web-app-into-an-app-server-container.html
Disclaimer: Noob.
Thank you, geeksters.
Problem solved:
ran docker-compose up on docker-compose and Dockerfile above, theContainer was built.
ran docker commit theContainer newImage:latest the only difference was adding :latest.
ran newImage, checked for files (present), pushed to Docker Hub, pulled and tested and it's all good.
Check out the image if curious: docker pull manningpart4/tomcat_test:latest (be sure to map port ie: 'docker run -p [Your Port]:8080 tomcat_test:latest')
kubectl get pods -n abc
NAME READY STATUS RESTARTS AGE
abc-v2-78b59ccc4f-85xgr 0/1 CrashLoopBackOff 27 129m
Facing below error:
> ➜ ~ kubectl logs -f abc-v2-78b59ccc4f-85xgr -n
Error: Unable to access jarfile abc.jar
I am assuming either jar is not present or required access is missing.
Pls guide me here, how to proceed.
Edit 1: As suggested by #howard-roark, Jar is available inside container, getting the same error message.
Edit 2: Check results now with .jar in java command
Edit 4: Ideally there should be only one instance with running status.
Kubernetes is a Container Orchestrator. It runs your images as Containers. The error you are showing looks like an application error and not a Kubernetes error. The way I would approach this is:
Check if the jar file your application calls is in your image. You can do this locally by running your image and exec'ing in to see if your jar file that your application runs is there.
docker run -it <image> /bin/bash
Or you can do a similar command via Kubernetes to exec into your pod:
kubectl run -i --tty testjavacontainer --image=<image> -- /bin/bash
If it is there, then I would confirm its path and make sure that my java command is correctly referencing that path. If it is not there, then I would adjust my Dockerfile to ensure it is at the path that my java command expects.
In short, I would approach this as a standard java error, with the nuance that it happens to run in a container.
I am trying to put a piece of open source software in a docker container (https://github.com/att/XACML) but in this container I can not use maven. The documentation for running this service says to use mvn jetty, which does work fine, but in order to get this in a container I don't want to include a build step (maven).
Instead, I'd like a way to compile the a war, so I can copy just the war into the container and execute it from there.
I have tried many attempts to get the war running without maven jetty but none of them work.
java -jar /path/to/jar
no main manifest attribute error. There is no main class, it extends an HttpServlet
using jetty-runner
when I launch the war with jetty-runner through the command line I do not get any errors, but it boots up to a page showing the directory of files, and not the actual project.
Making an 'uber-jar' to package all deps
same issue as 1, get a no main manifest issue.
I can include more code if that would be helpful (pom files etc), but I don't want to add too much if it is unneeded. I am super unfamiliar with how java projects are packaged and deployed, so I am having a difficult time figuring out what needs to be done.
Thanks!
Minimal Dockerfile to work with your webapp / war file is ...
FROM jetty:9.4.18
ADD ROOT.war /var/lib/jetty/webapps/
This uses the official jetty docker image at
https://hub.docker.com/_/jetty
Managed at
https://github.com/eclipse/jetty.docker
The name ROOT.war is special, and will deploy your webapp in the "root" context path of "/"
Building Image
If you build it like this ...
$ docker build -t stackoverflow/jetty:latest .
Running Image
Interactively (so you can the logs)
$ docker run --interactive --tty --rm --publish 80:8080 stackoverflow/jetty:latest
As Daemon
$ docker run --detach --publish 80:8080 stackoverflow/jetty:latest
The server will be available on port 80 of the machine you ran the docker run command on.
Configuring Jetty Base
If you need to configure the jetty image you can use any of the standard start.jar commands.
Example:
FROM jetty:9.4.18
WORKDIR $JETTY_BASE
RUN java -jar $JETTY_HOME/start.jar --add-to-start=jsp
ADD ROOT.war /var/lib/jetty/webapps/
How This Works Without Maven
See the official image details ...
https://github.com/eclipse/jetty.docker/blob/master/9.4-jdk11/Dockerfile
The key commands are ...
WORKDIR $JETTY_BASE
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["java","-jar","/usr/local/jetty/start.jar"]