Can't run docker image - java

First, sorry if my question sounds too easy or silly. I'm new to docker.
I have created my docker image and passed several jar files which are to be run immediately when the container starts.
I want to run the script "serve.sh" immediately when the container starts
I succeeded in creating the images well, but when I run the container, it throws me this error:
C:\Program Files\Docker\Docker\resources\bin\docker.exe: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-it\": executable file not found in $PATH": unknown.
Here is the command I use to run the image I craeted:
docker run b24b37614e1a -it
Here is my docker file:
FROM openjdk:8-jdk-alpine
EXPOSE 8080:8080
COPY apigateway-0.0.1-SNAPSHOT.jar apigateway.jar
COPY authservice-0.0.1-SNAPSHOT.jar authservice.jar
COPY institutionsservice-0.0.1-SNAPSHOT.jar institutionsservice.jar
COPY messagesservice-0.0.1-SNAPSHOT.jar messagesservice.jar
COPY postsservice-0.0.1-SNAPSHOT.jar postsservice.jar
COPY userservice-0.0.1-SNAPSHOT.jar userservice.jar
COPY serve.sh serve.sh
CMD [ "bash" "./serve.sh" ]
Please what am I doing wrong ? I'm new to docker

There are a couple of things which you should correct, First one is the CMD format which should be
CMD instruction has three forms:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)
CMD [ "/bin/bash" , "./serve.sh" ]
Another thing, When you do docker run, the instructions are
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
which means all the options has to be before IMAGE and in your case it is appearing after IMAGE.
The correct command should be
docker run -it b24b37614e1a
BTW, small question, why you want to run an interactive container of this application. Ideally, it should be something like
docker run -p $HOST_PORT:$APP_PORT b24b37614e1a
-p => Publish a container's port(s) to the host
and then you can access your application localhost:$HOST_PORT or machine_IP:$HOST_PORT

Keep in mind that docker args order matters:
you wrote docker run b24b37614e1a -it which is different from
docker run -it b24b37614e1a
Hope it solves your problem :)

tl;dr
docker run -it then args (c/o Luca Fabbian)
You don't have bash. Use sh. (c/o MC Emperor)
CMD exec form needs an array, so use commas: CMD ["sh", "./serve.sh"]
CMD has a shell form if you forget syntax easily: CMD ./serve.sh
Don't even exec the shell if you don't have to: CMD ["./serve.sh"]
Argument order matters
This assumes you already took Luca's advice:
Keep in mind that docker args order matters:
you wrote docker run b24b37614e1a -it which is different from docker run -it b24b37614e1a
You don't have bash.
I pulled the openjdk:8-jdk-alpine image to confirm, and it does not come with bash. Alpine images come with sh so the code provided will never work unless you correct the shell used or install bash.
"unknown operand"
From your response to nischay:
I get this error: "sh: ./serve.sh: unknown operand"
I updated My CMD instruction to: CMD [ "bin/bash" "./serve.sh" ]
CMD in the exec form takes an array of instructions. These must be separated by a comma.
Do this:
CMD [ "executable", "param1" ]
^
A note on using CMD
As nischay said, there are a few different ways to use CMD to do roughly the same thing, from the reference quoted.
You can in fact use the exec form of CMD to say things like:
CMD [ "sh", "./serve.sh" ]
Typing out /bin/sh or /bin/bash or whichever shell you want is not required unless desired. But if you don't need the shell, you can use exec form without the shell as well:
CMD [ "./serve.sh" ]

Related

Deploying Command Line Interface app using jib

Ok, I am building a jib based docker image which contains a java CLI app. The application is run like this :
java -jar app.jar --opt1=<opt1-value>
what i want to do is run a docker container which does nothing when the container is started but can accept arguments anytime and pass that arguments to the JVM application in the container and let it do its job. It looks like that when the jib docker container is run, the application is run and it closes itself.
Not sure how to go about doing this. Any help on this is much appreciated.
I think you're trying to use a container in an unconventional way, but I'll leave an answer anyway.
I'll assume you run your container image on a Docker runtime.
Run java -jar app.jar inside a container.
$ docker run --entrypoint java <your image> -jar app.jar
Run java -jar app.jar --opt1=some-value inside a container.
$ docker run --entrypoint java <your image> -jar app.jar --opt1=some-value
Run sh inside a container, and use the shell.
(This requires having the sh program installed in your image. An old version of Jib by default used a base image that doesn't have a shell program, so in that case, you would have needed to specify a different base image such as openjdk using the jib.from.image config option.)
$ docker run -it --entrypoint sh <your image>
(now you're in a "sh" process running inside a container)
# ls
...
# java -jar app.jar
...
# exit
Update based on the OP's comment:
There are many ways to achieve what you want, and here's one:
Run a container with a process that can hang while does nothing, such as the very common Linux tool sleep. (Again, as with sh above, you may use a base image that comes with the sleep binary, such as openjdk.)
$ docker run --name my-running-container --entrypoint sleep <your image> infinity
In another terminal, you'll be able to verify that your container named "my-running-container" is running with the command sleep infinity:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
51c4568d2d2a debian:buster "sleep infinity" 6 seconds ago Up 3 seconds my-running-container
When you want to run your app inside the running container, do
$ docker exec my-running-container java -jar app.jar --opt1=some-value

Docker Springboot not running

I am new to docker,
I have pre cooked a docker image(updated and installed Java and other dependancies) and stored it on my GitHub repo,
I have stored a simple hello world Spring Boot application on an AWS S3 bucket,
I want to my DockerFile -
1. Get the docker image from my GitHub repo
2. Do an update patch
3. Set my working to directory to /home/ubuntu
4. Download application from S3 bucket using wget(it's publicly accessible)
5. run the application inside the container
After which I will run the image.
Command to build -
docker build -t someTag .
Command to run -
docker run -p 9090:8090 someTag
My java application jar that will be downloded is - docker.jar
And the application runs on port 8080
I have the following Dockerfile -
FROM someRepoHere
WORKDIR /home/ubuntu
RUN apt-get update
RUN cd /home/ubuntu
VOLUME /home/ubuntu
RUN wget S3BucketLocationHere
#RUN nohup java -jar docker.jar &
# Expose the default port
EXPOSE 8080
#Old command - CMD nohup java -jar docker.jar &
CMD ["java", "-jar", "docker.jar"]
The DockerFile is able to successfully build the image but,
My application is unreachable, It did not run inside the container.
Locally if I wget my application and run the nohup command, the application responds successfully.
Your command being run is what controls the existence of the container, when it exits/returns, the container exits and stops. Therefore you need to run your command in the foreground. When you are in an interactive shell in a container, that command is your shell. The command you've listed uses a shell, but that shell exits when it runs out of commands to process and nothing is running in the foreground:
CMD nohup java -jar docker.jar &
The string syntax will run the command with /bin/sh -c "nohup java ...".
A better option is to run with json syntax if you don't need a shell, and run your java app in the foreground, avoid the nohup and background syntax:
CMD ["java", "-jar", "docker.jar"]
A few more comments on the provided Dockerfile:
WORKDIR /home/ubuntu
RUN apt-get update
That only creates a cache inside your container that will become stale and result in cache misses if you try to use it in the future. This doesn't upgrade any packages if that's what you intended. That line should be removed.
RUN cd /home/ubuntu
This makes no filesystem changes, and will have no impact on the resulting image. The current shell state is lost after the RUN line exits, including the current directory and any variables you set. This line should be removed.
VOLUME /home/ubuntu
From this line forward, changes to /home/ubuntu will be lost. You'll only see anonymous volumes created as a result unless you specify a volume at runtime at the same location. You likely don't want the above volume line because it will break things like the next line.
RUN wget S3BucketLocationHere
This line has been obfuscated but I suspect you are outputting in /home/ubuntu because of the value of WORKDIR. Anything created here will be lost because of the VOLUME line above.

Dockerized Java app dies with no error message but runs fine standalone

Please note: I know this questions is very similar to this one however you'll note that the solution in that case was to EXPOSE the port, which I am already doing. Hence although this questions sounds similar, I think its simply a different problem altogether with similar symptoms as the other question.
Docker Version 17.12.0-ce-mac49 (21995) here. I am experimenting with Docker for the first time and have built my first Docker image. My Dockerfile is:
FROM openjdk:8
RUN mkdir /opt/myapp
ADD build/libs/myapp.jar /opt/myapp
ADD application.yml /opt/myapp
ADD logback.groovy /opt/myapp
WORKDIR /opt/myapp
EXPOSE 9200
ENTRYPOINT java -Dspring.config=. -jar myapp.jar
I build it via:
docker build -t myapp .
Everything succeeds. I then tag it as if I'm going to push it to Quay:
docker tag <imageId> quay.io/myregistry/myapp:0.1.0-SNAPSHOT
However before I publish to Quay I want to run it locally to make sure it works:
docker run -it -p 9200:9200 -d --env-file /Users/myuser/myapp-local.env --name myapp myapp
When I run this I get an indication that the container is running, and I can even see it for a few seconds via docker ps:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3fa8f7a4288 myapp "/bin/sh -c 'java -D…" Less than a second ago Up 7 seconds 0.0.0.0:9200->9200/tcp myapp
However after a few seconds it stops running and disappears from docker ps altogether:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Furthermore I'm not able to SSH into the container:
docker exec -it f3fa8f7a4288 bash
Error: No such container: f3fa8f7a4288
...or see any logs/console output.
When I run myapp.jar outside of Docker (as a typical Spring Boot app, it starts up and runs beautifully without exceptions). How can I troubleshoot what is going on?
The docker logs command will show you the output a container is generating when you run it detached (with -d). This is likely to include the error message.
docker logs --tail 50 --follow --timestamps container
You can run the image in the foreground without the -d to see the output like when you run myapp.jar outside of Docker.
docker run my/image
So in this specific case:
docker run -it -p 9200:9200 --env-file /Users/myuser/myapp-local.env --name myapp myapp
If I am not mistaken, the issue you are experiencing is because you are using the shell form of ENTRYPOINT. Change it to use the exec version, as follows:
ENTRYPOINT ["java", "-Dspring.config=.", "-jar", "myapp.jar"]
The shell form will launch Java as a separate process just like a shell command. This causes PID 1 to return making Docker believe the container is finished. Using the exec form, the Java process replaces PID 1 and the container will continue running.

Cannot run executable from Dockerfile

I have tried in various ways to run the following command:
shell form:
CMD java -jar ImageTester.jar -ml LAYOUT -k $APIKEY -f ../screenshots -p $PROXY -s $URL
I get the following error:
/bin/sh: 1: java: not found
exec form:
CMD [ "java", "-jar", "ImageTester.jar", "-ml LAYOUT -k $APIKEY -f ../screenshots -p $PROXY -s $URL" ]
I get this error:
container_linux.go:247: starting container process caused "exec: \"java\": executable file not found in $PATH"
My Dockerfile:
FROM node:8
RUN node --version
RUN npm install
RUN npm i puppeteer
CMD [ "java", "-jar", "ImageTester.jar", "-ml LAYOUT -k $APIKEY -f ../screenshots -p $PROXY -s $URL" ]
As your can expect, this works in my local. What am I missing?
Your Dockerfile should either have a base image gotten from https://hub.docker.com/_/openjdk/ or equivalent
or your Dockerfile needs to install java before it can call it...
Java is not part of the standard commands on a linux machine.
you are using node which does not contain java but nodejs which is JavaScript :-) not the same...
Normally though if you want a node application to call a java application in docker it is good practice to create a node image with the node application and a java image with the java application and let them talk to each other.
See for best practices this article https://docs.docker.com/v17.09/engine/userguide/eng-image/dockerfile_best-practices/

Why does wildcard for jar execution not work in docker CMD?

I have a Dockerfile with the following CMD to start my spring boot app:
FROM java:8-jre
# ...
CMD ["java", "-jar", "/app/file*.jar"]
When I try to start a container from the created image I get:
Error: Unable to access jarfile /app/file*.jar
But when I override the CMD while starting the container and execute the command in the container everything works fine:
docker run -it <imageId> bash
root#<containerId>:/app# java -jar /app/file*.jar
<spring boot app starts...>
Is it possible to use wildcards with java -jar command using docker CMDs?
Please don't tell me not to use wildcards. I want to use it cause of reasons ;-)
Update
Based on the answer I was able to fix it:
CMD ["/bin/sh", "-c", "java -jar /app/file*.jar"]
This kind of asterisk expansion is done by the command line processor - the shell - and you circumvent that by invoking java directly.
Much the same way as commands should be invoked with "CMD /C" under Windows to get full treatment.
Invoke /bin/sh instead.
CMD java -jar /app/file*.jar worked for me

Categories