Passing JVM args to Docker image of Spring boot app on Kubernetes - java

I am trying to pass JVM args to Docker image of Spring boot app on Kubernetes. Specifically, I wanted to pass these three arguments:
-Djavax.net.ssl.trustStore=/certs/truststore/cacerts
-Djavax.net.ssl.trustStorePassword=password
-Djavax.net.debug=ssl
I tried adding it to "env" section with name as "JAVA_OPTS", "JDK_JAVA_OPTIONS" and "JAVA_TOOL_OPTIONS", none of which seemed like they were working.
I also tried adding it under "args" section, that did not work either. At best I get no change in behaviour at all, at worst my pods won't start at all with this error:
Error: failed to create containerd task: OCI runtime create failed:
container_linux.go:380: starting container process caused:
process_linux.go:545: container init caused: setenv: invalid argument:
unknown
Entry point in Dockerfile is defined as such:
ENTRYPOINT ["java","-jar","/app/appname-exec.jar"]
Any ideas?

To override the container's default ENTRYPOINT setting, I sometimes do the following:
containers:
- name: my-container
image: mycontainer:latest
command: ["java"]
args: ["-Djavax...", "-Djavax...", "-jar", "myapp.jar"]
You can define content in the manifest that you would describe in a Dockerfile. In args section, you can describe as many settings as you want.

Related

Issue with Building Java Application in Docker

I am at the Java Directory. And When I execute the build command:
docker build -t karthikjohnbabu/hello-world-java:0.0.2.RELEASE .
I get the below error message. Please help me???
failed to solve with frontend dockerfile.v0: failed to create LLB definition: no match for platform in manifest sha256:195e9c227ad891282e80602cac2372a3085ecf4ceefbb395558ffe0f7bb0b9aa: not found.
Complete details of error below:
Try adding the following arg to the command:
--platform=linux/amd64
or alternatively use the following command to set an env var:
export DOCKER_DEFAULT_PLATFORM=linux/amd64
The information you gave leaves room for guessing.
I believe the important part is no match for platform in manifest.
Thus I believe in your dockerfile you start FROM someimage, and this someimage is not available for the platform you are using (which could mean MacOS).

Cloud Foundry : How to deploy spring boot app with an additional JVM command

I am using Pivotal to host Spring boot app in Cloud Foundry. I am able to deploythe app without any commands fine. But my requirement is to run with an additional JVM command as a workaround for this issue
-Doracle.jdbc.timezoneAsRegion=false
Running with below manifest I get error,
---
applications:
- name: gl-bo-sample
command: java -jar -Doracle.jdbc.timezoneAsRegion=false
path: ./target/backoffice-1.0-SNAPSHOT.jar
buildpacks:
- https://github.com/cloudfoundry/java-buildpack.git
CF Log
2019-11-29T16:33:45.606+05:30 [CELL/0] [OUT] Cell f38e366a-22ac-45ee-9dba-73e1f505525a creating container for instance e1475d2b-0c8e-4766-7e13-6da7
2019-11-29T16:33:45.952+05:30 [CELL/0] [OUT] Cell f38e366a-22ac-45ee-9dba-73e1f505525a successfully created container for instance e1475d2b-0c8e-4766-7e13-6da7
2019-11-29T16:33:46.958+05:30 [CELL/0] [OUT] Starting health monitoring of container
2019-11-29T16:33:47.168+05:30 [APP/PROC/WEB/0] [ERR] bash: java: command not found
2019-11-29T16:33:47.179+05:30 [APP/PROC/WEB/0] [OUT] Exit status 127
2019-11-29T16:33:47.182+05:30 [CELL/SSHD/0] [OUT] Exit status 0
2019-11-29T16:33:47.385+05:30 [CELL/0] [OUT] Cell f38e366a-22ac-45ee-9dba-73e1f505525a stopping instance e1475d2b-0c8e-4766-7e13-6da7
2019-11-29T16:33:47.385+05:30 [CELL/0] [OUT] Cell f38e366a-22ac-45ee-9dba-73e1f505525a destroying container for instance e1475d2b-0c8e-4766-7e13-6da7
2019-11-29T16:33:47.402+05:30 [API/2] [OUT] Process has crashed with type: "web"
Could some one tell how to achieve this or any other approach to achieve this. Thanks.
OK, a few things for you.
command: java -jar -Doracle.jdbc.timezoneAsRegion=false
When using the Java buildpack, don't set command unless you really, really know what you're doing. It can cause problems as you are totally overriding the command set by the Java buildpack.
If you set a command, you need to make sure that you undo it. You can do this by removing it from your manifest.yml and by running cf push -c null. The -c null will tell the server side to remove the save command and go back to using what the Java buildpack decides. The other option is to cf delete your app, but that's not always possible.
To set JVM arguments, you can simply cf set-env <app> JAVA_OPTS '-Doracle.jdbc.timezoneAsRegion=false, or by setting them in your manifest.yml. You can add an env: block with env variables in it.
Ex:
...
env:
JAVA_OPTS: -Doracle.jdbc.timezoneAsRegion=false
...
This works because the Java buildpack includes $JAVA_OPTS in the start command, so anything you put in there is substituted into the command which starts your app.
If you have an executable JAR you can also use cf set-env <app> JBP_CONFIG_JAVA_MAIN '{ arguments: "--server.port=9090 --foo=bar" }' to set app arguments. This option is used to set argv arguments which get processed by the app itself, not the JVM. In the same way as JAVA_OPTS, you can set this within the env: block of your manifest.yml.
For what it's worth, the reason you get bash: java: command not found is because the Java buildpack does not put java on the PATH. You need to set the full path to the java process which is at $HOME/.java-buildpack/open_jdk_jre/bin/java. So if you use the full path, you could make what you're doing above work. That said, it's strongly recommended you do not set command.
Side note. Don't point buildpack to https://github.com/cloudfoundry/java-buildpack.git. You're pointing to the master branch when you do this which is a moving target. You should generally use the buildpack provided by your platform, i.e. cf buildpacks, or add a release tag to the URL like https://github.com/cloudfoundry/java-buildpack.git#v4.26 to get v4.26 of the Java buildpack.
You can declare it in application.properties and it should work fine.

Cannot connect to Wildfly in Dockerfile

I'm creating a custom Dockerfile with extensions for official keycloak docker image. I want to change web-context and add some custom providers.
Here's my Dockerfile:
FROM jboss/keycloak:7.0.0
COPY startup-config.cli /opt/jboss/tools/cli/startup-config.cli
RUN /opt/jboss/keycloak/bin/jboss-cli.sh --connect --controller=localhost:9990 --file="/opt/jboss/tools/cli/startup-config.cli"
ENV KEYCLOAK_USER=admin
ENV KEYCLOAK_PASSWORD=admin
and startup-config.cli file:
/subsystem=keycloak-server/:write-attribute(name=web-context,value="keycloak/auth")
/subsystem=keycloak-server/:add(name=providers,value="module:module:x.y.z.some-custom-provider")
Bu unfortunately I receive such error:
The controller is not available at localhost:9990: java.net.ConnectException: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: Connection refused
The command '/bin/sh -c /opt/jboss/keycloak/bin/jboss-cli.sh --connect --controller=localhost:9990 --file="/opt/jboss/tools/cli/startup-config.cli"' returned a non-zero code: 1
Is it a matter of invalid localhost? How should I refer to the management API?
Edit: I also tried with ENTRYPOINT instead of RUN, but the same error occurred during container initialization.
You are trying to have Wildfly load your custom config file at build-time here. The trouble is, that the Wildfly server is not running while the Dockerfile is building.
Wildfly actually already has you covered regarding automatically loading custom config, there is built in support for what you want to do. You simply need to put your config file in a "magic location" inside the image.
You need to drop your config file here:
/opt/jboss/startup-scripts/
So that your Dockerfile looks like this:
FROM jboss/keycloak:7.0.0
COPY startup-config.cli /opt/jboss/startup-scripts/startup-config.cli
ENV KEYCLOAK_USER=admin
ENV KEYCLOAK_PASSWORD=admin
Excerpt from the keycloak documentation:
Adding custom script using Dockerfile
A custom script can be added by
creating your own Dockerfile:
FROM keycloak
COPY custom-scripts/ /opt/jboss/startup-scripts/
Now you can simply start the image, and the built features in keycloak (Wildfly feature really) will go look for a config in that spedific directory, and then attempt to load it up.
Edit from comment with final solution:
While the original answer solved the issue with being able to pass configuration to the server at all, an issue remained with the content of the script. The following error was received when starting the container:
=========================================================================
Executing cli script: /opt/jboss/startup-scripts/startup-config.cli
No connection to the controller.
=========================================================================
The issue turned out to be in the startup-config.cli script, where the jboss command embed-server was missing, needed to initiate a connection to the jboss instance. Also missing was the closing stop-embedded-server command. More about configuring jboss in this manner in the docs here: CHAPTER 8. EMBEDDING A SERVER FOR OFFLINE CONFIGURATION
The final script:
embed-server --std-out=echo
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false)
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false)
stop-embedded-server
WildFly management interfaces are not available when building the Docker image. Your only option is to start the CLI in embedded mode as discussed here Running CLI commands in WildFly Dockerfile.
A more advanced approach consists in using the S2I installation scripts to trigger CLI commands.

Is it possible to use a local Docker image in a docker-compose file for DockerComposeContainer?

In my docker-compose.yaml file I use the image "my-service" (among other remote images that work fine)
version: "2"
services:
myservice:
image: my-service
Normally I build the "my-service" image with maven using the io.fabric8 docker-maven-plugin.
My Dockerfile:
FROM vertx/vertx3-alpine
ENV VERTICLE_HOME /opt/lib
ENV NAME my-service
ENV EXEC_JAR_NAME my-service.jar
COPY target/my-service-1.0-SNAPSHOT.jar $VERTICLE_HOME/$EXEC_JAR_NAME
COPY target/lib $VERTICLE_HOME
COPY src/main/resources/settings.json /etc/company/myservice/settings.json
ENTRYPOINT ["sh", "-c"]
CMD ["java -cp $VERTICLE_HOME/$EXEC_JAR_NAME com.company.myservice.MyVerticle"]
Is there a way using the DockerComposeContainer from Testcontainers for docker-compose to use my local image of my-service?
This is my test set up
public class MyServiceIT {
#ClassRule
public static DockerComposeContainer compose =
new DockerComposeContainer(new File("src/test/resources/docker-compose.yml"));
Currently I get the following error message as it is using local images.
7:15:34.282 [tc-okhttp-stream-454305524] INFO 🐳 [docker/compose:1.8.0] - STDERR: pull access denied for my-service, repository does not exist or may require 'docker login'
17:15:34.283 [main] WARN org.testcontainers.containers.DockerComposeContainer - Exception while pulling images, using local images if available
It sounds like I need to build the image for use in my test, but I am not sure how to do that.
That's not an error message, but just a warning if docker-compose pull fails, see here.
You can also make Docker Compose build the images for you (although it is highly recommended to use withLocalCompose(true) in that case)

Use docker-machine create from java

I have an application that (I want to) uses Java to start and stop Docker containers. It seems that the way to do this is using docker-machine create, which works fine when I test from the command line.
However, when running using Commons-Exec from Java I get the error:
(aa4567c1-058f-46ae-9e97-56fb8b45211c) Creating SSH key...
Error creating machine: Error in driver during machine creation: /usr/local/bin/VBoxManage modifyvm aa4567c1-058f-46ae-9e97-56fb8b45211c --firmware bios --bioslogofadein off --bioslogofadeout off --bioslogodisplaytime 0 --biosbootmenu disabled --ostype Linux26_64 --cpus 1 --memory 1024 --acpi on --ioapic on --rtcuseutc on --natdnshostresolver1 off --natdnsproxy1 on --cpuhotplug off --pae on --hpet on --hwvirtex on --nestedpaging on --largepages on --vtxvpid on --accelerate3d off --boot1 dvd failed:
VBoxManage: error: Could not find a registered machine with UUID {aa4567c1-058f-46ae-9e97-56fb8b45211c}
VBoxManage: error: Details: code VBOX_E_OBJECT_NOT_FOUND (0x80bb0001), component VirtualBoxWrap, interface IVirtualBox, callee nsISupports
VBoxManage: error: Context: "FindMachine(Bstr(a->argv[0]).raw(), machine.asOutParam())" at line 500 of file VBoxManageModifyVM.cpp
I have set my VBOX_USER_HOME variable in an initializationScript that I'm using to start the machine:
export WORKERID=$1
export VBOX_USER_HOME=/Users/me/Library/VirtualBox
# create the machine
docker-machine create $WORKERID && \ # create the worker using docker-machine
eval $(docker-machine env $WORKERID) && \ # load the env of the newly created machine
docker run -d myimage
And I'm executing this from Java via the Commons Exec CommandLine class:
CommandLine cmdline = new CommandLine("/bin/sh");
cmdline.addArgument(initializeWorkerScript.getAbsolutePath());
cmdline.addArgument("test");
Executor executor = new DefaultExecutor();
If there is another library that can interface with docker-machine from Java I'm happy to use that, or to change out Commons Exec if that's the issue (though I don't understand why). The basic requirement is that I have some way to get docker-machine to create a machine using Java and then later to be able to use docker-machine to stop that machine.
As it turns out the example that I posted should work, the issue that I was having is that I was provisioning machines with a UUID name. That name contained dash (-) characters which apparently break VBoxManage. This might be because of some kind of path problem but I'm just speculating. When I changed my UUID to have dot (.) instead of dash it loaded and started the machine just fine.
I'm happy to remove this post if the moderators want, but will leave it up here in case people are looking for solutions to problems with docker-machine create naming issues.

Categories

Resources