I'm trying to run a docker container that contains both a java jar server and nginx in front of it to perform subdomain->port forwarding, and I don't seem to be setting it up correctly.
This is my Dockerfile:
FROM java:8
MAINTAINER somefool
RUN apt-get update
RUN apt-get -y install nginx
COPY theBigOwlServer.jar /data/server.jar
RUN rm -v /etc/nginx/nginx.conf
ADD nginx.conf /etc/nginx/
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80 8080
CMD java -jar /data/server.jar
CMD service nginx start #<--- line AAA
The java jar listens on ports 8080 and 8090. When I run this container with -p 80:80 -p 8080:8080, the jar just doesn't seem to start. I don't see any console output from it, and I can't reach it from outside the container with curl localhost:8080. I can reach nginx on port 80, but requests that should be forwarding to the jar are coming back with an empty reply.
However, if I comment out line AAA, then the jar starts fine. It generates console output and curl localhost:8080 reaches it. How can I run nginx and the jar together?
Docker containers are designed for single-process sandboxing, so only take one CMD argument. In this case it's just picking up the last one in the file. If you need to run multiple prorcesses in a container (and sometimes it makes sense to do so) then use something like Supervisor to run your commands for you (so your CMD would run Supervisor). Then you get goodies like process watchdogs and such thrown in too.
You could do something like:
ENTRYPOINT sh -c 'service nginx start && java -jar /data/server.jar'
I tried this out and it worked for me.
Related
I am trying to dockerize a full-stack Java(Springboot)-Angular app. The Angular app is embedded in the application and makes REST calls to the Java app as GET localhost:8080/getSomeInfo. My Dockerfile is as
FROM maven:3.6.3-openjdk-8 AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
FROM openjdk:8-jdk-alpine
COPY --from=build /home/app/target/*.jar /usr/local/lib/app.jar
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} /usr/local/lib/app.jar
ENTRYPOINT ["java","-jar","/usr/local/lib/app.jar"]
FROM node:12.2.0
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY src/main/web/package.json /app/package.json
RUN npm install
RUN npm install -g #angular/cli#10.1.2
COPY src/main/web /app
CMD ng serve --host 0.0.0.0
I build it as
docker build -t springio/myapp .
I need to expose both the angular port and the java port, so I run it as
docker run -p 9898:4200 -p 8080:8080 -t springio/myapp
I am able to bring up the web page, but it cannot reach out to the Java server (can't connect to 8080). How can this be fixed please?
I have tried putting 'EXPOSE 8080' in the dockerfile, but that did not work
You should not put 2 applications in the same container. Although you can, it is considered a bad practise and it defeats the purpose of using containers.
I suggest having 2 Dockerfile: one for the back-end (java app) and one for the front-end (Angular app). Build each of them separately and start them independently.
For your specific problem I don't think the port is the problem, but is the Java app that is not even starting (it is actually not even present in the final image). Splitting the Dockerfile and starting the apps separately will fix your issue.
EXPOSE doesn't actually do anything. It is there to inform users of the Dockerfile which ports the application is listening on, so that they know which ports to map on the host.
I have a Dockerfile which looks like this:
FROM alpine:3.9
RUN apk add --update openjdk8
RUN mkdir /var/generator/
COPY generator.jar /var/generator
EXPOSE 8080
ENTRYPOINT [ "/bin/sh" ]
Dockerfile is inside generator/ folder. I am building it using:
docker build -t generator generator/
It builds successfully:
Successfully built 878e81f622cc
Successfully tagged generator:latest
but when I am trying to run this image with
docker run -d -p 8080:8080 generator
it dies immediately. docker logs gives no output.
What is wrong with my Dockerfile? Why is the container dying?
Try to run the JAR. Currently, it just runs sh command and exits. Make it something as below to run the JAR in foreground -
FROM alpine:3.9
RUN apk add --update openjdk8
RUN mkdir /var/generator/
COPY generator.jar /var/generator
EXPOSE 8080
ENTRYPOINT ["java","-jar","/var/generator/generator.jar"]
Beside your entrypoint is wrong (sh exits immediately) I would also recommend to start with an appropriate base image instead of starting with alpine and installing the openjdk package. Since you want to run a java application just use the JRE and not a full JDK and start the application as a foreground process.
Here's a minimal version which is also more efficient in disksize as the image will be smaller.
FROM openjdk:8-jre-alpine
COPY generator.jar /opt/generator.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/opt/generator.jar"]
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.
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.
I want to build and run my Java Maven web app in a docker container. I tried with a following command:
docker run -it --name my_project -v "$PWD":/usr/src/my_project -w /usr/src/my_project maven:3.5.0-jdk-8 mvn clean install tomcat7:run
It correctly copies the resources, run maven clean install (successful build) and run with tomcat7-maven-plugin that is included in my pom.xml.
Everything works fine and logs are really similar to build and run locally on my windows machine:
Unfortunately on a web browser there is information "connection refused".
What could potentially cause the problem?:
- my application is windows specific and cannot run on linux?
- app is fully app and running but something wrong is with proxy configuration or port is not configured?
How can i proceed further - investigate the logs? Try to build on windows docker container?
P.S. I check IP of a container with Kitematic app for windows docker.
Possibly three issues. Once your used -w instead of -v
docker run -it --name my_project -v "$PWD":/usr/src/my_project -w /usr/src/my_project maven:3.5.0-jdk-8 mvn clean install tomcat7:run
Which I assumed was a Typo while posting. Next you didn't publish the port on your machine
docker run -p 9998:9998 -it --name my_project -v "$PWD":/usr/src/my_project -w /usr/src/my_project maven:3.5.0-jdk-8 mvn clean install tomcat7:run
This would map the port 9998 (right side) from your container to the port 9998 on your localhost.
Third and last one, your INFO log says listening on localhost:9998. This is not good. Because that means your war is listening from traffic generated inside the the container only and not from outside the container. You need to configure your war so it listens on all interfaces inside the container and bind should be 0.0.0.0:9998