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.
Related
I have a backend that runs on Spring and I had to create a Docker container.
To do this, I created a .jar file using Maven by running this mvn package then I did the docker run build command to create my container.
Here is the first content of my DockerFile.
FROM openjdk:17-jdk-alpine
COPY target/dwh_webservices-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 443
ENTRYPOINT ["java", "-jar", "/app.jar"]
I want to point out that my Container is perfectly functional with this first method.
However, it's a pain to have to run the command every time. Moreover, I would like to make pipelines and automate the creation of the .JAR with Maven. So I decided to integrate the creation of the .JAR in the Dockerfile.
For that, I followed this question that explains the Multi-stage and I created this Dockerfile :
#
# Build stage
#
FROM maven:3.8.3-openjdk-17 as build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
#
# Package stage
#
FROM openjdk:17-jdk-alpine
COPY --from=build /home/app/target/dwh_webservices-0.0.1-SNAPSHOT.jar /usr/local/lib/app.jar
EXPOSE 443
ENTRYPOINT ["java", "-jar", "/app.jar"]
And when I run it, I have this error that appears:
com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host BACKENDSERV, port 1433 has failed. Error: "BACKENDSERV Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.
Since it's the exact same source code plus the fact that the first .jar is working, then it should also work. Why, when using the second method, does the application fail to access the host?
What causes this change?
I am playing around with a docker project that builds and starts with
docker run -p 8888:8888 -v /$(pwd)/example/proto:/proto <image-name>
Inside it is a gradle based java application, about which I would like to get to know somewhat more, so I started to modify its source, adding some logs etc.
I tried to rebuild and rerun the docker image the above way but the results of my modifications don't seem to visible, the logs aren't printed etc.
I removed the image with docker rmi, but after every rebuild it seems to be the same image is being created. docker images always shows it is created 3 weeks ago and the image id is always the same
Checking on the application level the build directory contains the newly compiled java classes, so apparently on that level my changes are in effect, but it seems docker still uses the old code
Any help would be appreciated
Updated: Dockerfile
FROM gradle:7.0.0-jdk11 as cache
RUN mkdir -p /home/gradle/cache_home
RUN mkdir -p /proto
RUN touch /proto/any.proto
ENV GRADLE_USER_HOME /home/gradle/cache_home
COPY build.gradle /home/gradle/java-code/
COPY gradle.properties /home/gradle/java-code/
WORKDIR /home/gradle/java-code
RUN gradle build -i --no-daemon || return 0
FROM gradle:7.0.0-jdk11 as runner
COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle
COPY . /usr/src/java-code/
WORKDIR /usr/src/java-code
EXPOSE 8888
ENTRYPOINT ["gradle", "bootRun", "-i"]
A docker build will send your local changes to your local docker deamon to be built into an image.
cd projectWithDockerfile
docker build -f ./Dockerfile -t me/gradlethingy .
docker run -p 8888:8888 -v /$(pwd)/example/proto:/proto me/gradlethingy
Without the build I'm guessing you are pulling in their <image-name> from the net each time.
I have a simple Dockerfile in my spring boot as follow. I am able to build the image successfully locally, and can push using my credentials.
But my build keeps failing on every attempt to build automatically.
FROM openjdk:8-jdk-alpine
LABEL maintainer="xxxxx#xxx.com"
VOLUME /tmp
EXPOSE 8080
ARG JAR_FILE=target/jollof.jar
ADD ${JAR_FILE} jollof.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-
jar","/jollof.jar"]
From docker hub, I got this from the log.
Building in Docker Cloud's infrastructure...
Cloning into '.'...
Warning: Permanently added the RSA host key for IP address 'xxx.xx.xxx.xxx' to
the list of known hosts.
....
....
Step 6/7 : ADD ${JAR_FILE} jollof.jar
ADD failed: stat /var/lib/docker/tmp/docker-
builder674045875/target/jollof.jar:
no such file or directory
Unlike your local environment, Docker Hub fetches then builds your project in a fresh environment, so that the file target/jollof.jar that is intended to be copied is not available in the docker context. Hence the error you observe.
So I'd suggest refactoring your Dockerfile so that mvn package or so is done in the Dockerfile itself (which is a best practice to adopt, for the sake of reproducibility). Note that this configuration will be working for Docker Hub's automated builds as well as the builds in your local environment.
For example, below is an example Dockerfile that inspired by the that of this SO answer How to convert a Spring-Boot web service into a Docker image? as well as the Dockerfile of your post:
FROM maven:3.6-jdk-8 as maven
WORKDIR /app
COPY ./pom.xml ./pom.xml
RUN mvn dependency:go-offline -B
COPY ./src ./src
# TODO: jollof-* should be replaced with the proper prefix
RUN mvn package && cp target/jollof-*.jar app.jar
# Rely on Docker's multi-stage build to get a smaller image based on JRE
FROM openjdk:8-jre-alpine
LABEL maintainer="xxxxx#xxx.com"
WORKDIR /app
COPY --from=maven /app/app.jar ./app.jar
# VOLUME /tmp # optional
EXPOSE 8080 # also optional
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app/app.jar"]
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 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