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 am following the ISTIO tutorial for Service Mesh, and I am having problems to copy one of the steps they do.
https://docs.huihoo.com/microservices/introducing-istio-service-mesh-for-microservices.pdf
They have a java application called Recommendation, which they deploy twice.
docker build -t example/recommendation:v1 .
docker build -t example/recommendation:v2 .
I have a Java application, TEST, deployed in OpenShift which I want to copy and change the version, so I have TEST-V1 and TEST-V2. How can I do it? Do I need to deploy the application twice with different Deployment.yaml?
Thanks in advance.
How can I do it? Do I need to deploy the application twice with different Deployment.yaml?
Basically - yes. At the end, what you need, are two service endpoints pointing to different pods. You may place the service endpoints into the same deployment file, but for sake of robustness I'd use complete different deployment.
First of all, your commands:
docker build -t example/recommendation:v1 .
docker build -t example/recommendation:v2 .
are not deployment.
What you do is building docker image.
This is the line to deploy your service for the first example:
oc apply -f <(istioctl kube-inject -f \ src/main/kubernetes/Deployment.yml) -n tutorial
and second:
Finally, inject the Istio sidecar proxy and deploy this into Kubernetes:
oc apply -f <(istioctl kube-inject -f \ src/main/kubernetes/Deployment-v2.yml) -n tutorial
You ask if you need to deploy 2 times if you change version. First of all, you need to know that you are operating on containers. The docker build command creates a container for you that you will use later. If you create a new version of the application, you should create a new container. They are similar but not identical. That means, that are completely diffent docker images from the OpenShift / Kubernetes point of view. Every time you change the container image, you need to do deploy to Kubernetes / OpenShift. You need to do it one time for each docker image change.
I am trying to have a java program that is built with maven to run on a docker-compose scenario and hot reload as I make changes.
I added trava-jdk libvm on top of the original libvm and added the hotswapagent lib on the proper place. It gives me what I want when I run java -version
Starting HotswapAgent '/usr/local/openjdk-11/lib/hotswap/hotswap-agent.jar'
HOTSWAP AGENT: 10:18:24.771 INFO (org.hotswap.agent.HotswapAgent) - Loading Hotswap agent {1.4.0} - unlimited runtime class redefinition.
HOTSWAP AGENT: 10:18:24.992 INFO (org.hotswap.agent.config.PluginRegistry) - Discovered plugins: [JdkPlugin, Hotswapper, WatchResources, ClassInitPlugin, AnonymousClassPatch, Hibernate, Hibernate3JPA, Hibernate3, Spring, Jersey1, Jersey2, Jetty, Tomcat, ZK, Logback, Log4j2, MyFaces, Mojarra, Omnifaces, ELResolver, WildFlyELResolver, OsgiEquinox, Owb, Proxy, WebObjects, Weld, JBossModules, ResteasyRegistry, Deltaspike, GlassFish, Vaadin, Wicket, CxfJAXRS, FreeMarker, Undertow, MyBatis]
openjdk version "11.0.5" 2019-10-15
OpenJDK Runtime Environment 18.9 (build 11.0.5+10)
Dynamic Code Evolution 64-Bit Server VM 18.9 (build 11.0.5+5-202001261315, mixed mode)
My dockerfile to achieve that is the one below
FROM maven:latest
WORKDIR /tmp
RUN wget https://github.com/TravaOpenJDK/trava-jdk-11-dcevm/releases/download/dcevm-11.0.5%2B5/java11-openjdk-dcevm-linux.tar.gz
RUN tar -xvf java11-openjdk-dcevm-linux.tar.gz
RUN mv dcevm-11.0.5+5 /dcevm
WORKDIR /dcevm
RUN rm /usr/local/openjdk-11/lib/server/libjvm.so
RUN cp /dcevm/lib/server/libjvm.so /usr/local/openjdk-11/lib/server/
RUN cp -r /dcevm/lib/hotswap /usr/local/openjdk-11/lib/
Now I find myself a little lost on how to apply the hot reload on the Ide and properly run the code.
In case you are wondering why I need such a hack I have an IoT environment that has E2E tests and I wanted to be able to quickly iterate on new tests or failing tests without needing to recompile or restart containers.
I don't have an experience of working with this concrete hotswap agent, but in general to answer your question:
When you build the docker image, you are supposed to run your own application after all (via maven, with java -jar or in any other way) So, When you start the application process, you're supposed to make the application ready for remote debugging:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9999
You should expose a debug port in docker so that the IDE will connect to that port on host machine and it will be routed to port 9999 in docker container.
Make sure the application is running
In IDE create "Remote Debug configuration, in IntelliJ: Run/Debug Configurations -> Remote -> create new configuration and specify the host and exposed port that you've created during the step 2. You're supposed to be able to connect and place breakpoints in the code that will interact with IDE
If you do some change in some source file, right click and compile it while you're connected to remote debugging session.
If the change can be done, it will use hotswap at this point and will "upload" the new bytecode to the remote process right inside the docker in this case and will apply this changes without a reload.
By default JVM already provides Hotspot capabilities, but this library, I believe should provide more flexible/powerful options.
There is project HotswapDocklands dedicated to runnig HotswapAgent+dcevm in Docker. It is using mapping of in-Docker /extra_class_path directory to directory out of Docker. Then all modifications done on any file inside extra_class_path are "hotspapped" using extraClassPath to dcevm. To attach debugger you have to run dcevm with jdwp and expose debugger port from Docker.
I am using java 1.8 and spring-boot-starter-parent 1.5.6.RELEASE and swagger2 2.6.1. We run the application in the VM using the following command,
nohup java -jar myApplication.jar &
My application is getting stopped when the VM is stopped. So manually I need to start my application. I don't want to do that manually. I need to restart my application programmatically or any script will do this that is also fine for me.
How do I restart my application when VM is started??
Kindly provide your inputs.
In a Linux distribution which uses systemd (official docs here) (such as Debian, Ubuntu, or Fedora), creating a service is simple:
We'll need to create a service file which tells systemd how to start your application. Create a file in /etc/systemd/system named something like myApplication.service containing these lines:
[Unit]
Description="A description of what my application does"
[Service]
ExecStart=/path/to/java -jar /path/to/your/myApplication.jar
[Install]
WantedBy=multi-user.target
(Derived from an example in the docs.)
Then run systemctl enable myApplication.service as root to enable it, which will make it run on boot.
There's lots more you can learn; the docs for systemd are quite good. You might take a look at the blog story which introduced systemd as well, as that provides something of a "sales pitch" for what it can do.
I am new to docker. I want to run my java application on tomcat server using docker images/containers. Can anyone suggest best method to do that?
First find a docker image with the version of tomcat you want. You can search docker images using, docker search so try
docker search tomcat
next pull it locally
docker pull <your/image>
then run commands on it to install your software
docker run <your/image> <your command and args>
then find your container ID by running
docker images
and commit you changes
docker commit <container_id> <some_name>
I'd recommend the docker tutorial to get started.
P.S. this answer will show you how to transfer files to docker.