docker-compose failed to build on windows 10 - java

I'm trying to deploy my spring boot application with docker compose but get this error:
Step 14/15 : COPY ${JAR_FILE} manager.jar
ERROR: Service 'manager' failed to build : When using COPY with more than one source file, the destination must be a directory and end with a /
But if I do a docker build using the Dokerfile it works correctly. The question is, why fail with docker-compose up?.
C:\Push\Workspace\manager>docker build --tag "docker-manager:latest" .
[+] Building 7.3s (8/8) FINISHED
I have tried looking for examples but I am using windows 10
The Dockerfile:
FROM openjdk:8-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} example.jar
ENTRYPOINT ["java", "-jar", "example.jar"]
The docker-compose.yml
services:
oracle:
image: container-registry-london.oracle.com/database/enterprise:12.2.0.1
ports:
- "8080:8080"
- "1521:1521"
manager:
build: .
ports:
- "8181:8181"
depends_on:
- oracle
links:
- oracle
restart: always

I am guessing there might be mulitple jar files in your target folder.
In stead of using the *.jar , please use full name of the jar and then rebuild the dokcer compose file with --build flag.
ARG JAR_FILE=target/test-0.0.1-SNAPSHOT.jar
Then build with
docker-compose up --build

Related

How to build binaries outside of Dockerfile for docker-compose build

I am new to docker-compose and probably don't understand the ideology behind.
Short question -- I see there is docker-compose build command. I'd like to trigger a (gradle) script outside of the Dockerfile file as part of running it.
Let's say that I have a java web service inside Docker that I build in advance by gradle.
I don't add gradle agent to the Dockerfile (as I am expected to keep it small, right?), I only COPY binaries
FROM openjdk:17-jdk-alpine
RUN apk add --no-cache bash
VOLUME /var/log/app/
WORKDIR /app
ARG EXTRACTED
COPY ${EXTRACTED}/application/ ./
...
ENTRYPOINT ["java","org.springframework.boot.loader.JarLauncher"]
And so I build this image by a script
./gradlew build
java -Djarmode=layertools -jar build/libs/*.jar extract --destination build/libs-extracted/
docker build --build-arg EXTRACTED=build/libs-extracted -t my-server .
I can define the following compose.yml. How do I trigger gradle inside of it? Or, same as with my single Dockerfile, I am expected to wrap docker-compose build into a build script?
version: '3.1'
services:
db:
image: postgres:alpine
restart: always
my-server:
image: my-server
restart: always
depends_on:
- db
Maybe I am asking for a hack, but actually I am happy to take another approach if it's cleaner
I discovered multi-stage Dockerfile feature that addresses my task, and I can use it for both individual Dockerfile builds and docker-compose builds.
https://stackoverflow.com/a/61131308/1291049.
I will probably lose gradle daemon optimisations though.
Change your docker compose file:
version: '3.1'
services:
db:
image: postgres:alpine
restart: always
my-server:
build:
context: ./my-server
dockerfile: Dockerfile
restart: always
depends_on:
- db

Intellij idea use docker-compose can't mappeed native file to the remote docker

I just want to deploy my springboot applicaiton on the remote centos server through the intellij idea.
First I tried the way of DockerFile to deploy the application on intellij idea and I successed.
this is my DockerFile config
FROM williamyeh/java8
# COPY or ADD to image
COPY dockerdemo-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c "touch /app.jar"
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
but when I tried the method of docker-compose.yml,I failed,I can't mapped my navtive jar to the remote system.my docker-compose.yml config is
version: "3"
services:
dockerDemo2:
image: adoptopenjdk/openjdk8:latest
container_name: dockerDemo2
privileged: true
environment:
TZ: Asia/Shanghai
LANG: es_US.UTF-8
volumes:
- ./dockerdemo-0.0.1-SNAPSHOT.jar:/docker/dockerdemo-0.0.1-SNAPSHOT.jar
command: bash -c " tail -f /dev/null "
ports:
- 8080:8080
I deployed successed,but when I get in the remote docker ,I found the /docker/dockerdemo-0.0.1-SNAPSHOT.jar is a directory, It should expected as a jar file,but it not,I don't know why that.that's really confuesed me.

Docker Compose getting exception

I have a spring boot application which i have deployed on docker container, everything is working fine, but i want to deploy and run the application in docker container with docker compose.
This is my DockerFile
FROM java:8
VOLUME /tmp
COPY /target/order-0.0.1-SNAPSHOT.jar order.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/order.jar"]
Step 1 :- Created jar with mvn clean package
Step 2 :- docker build -t order
Step 3 :- docker run -it -d -p 8080:8080
Here everything work's fine
But if i don't execute the step 1 and want's to deploy the the application in container with docker-compose.
While trying to execute docker-compose up i am getting exception /target/order-0.0.1-SNAPSHOT.jar not found
So how to execute the mvn package command in docker-compose ?
Is their any other way's to acheive this ?
This is my docker-compose.yml
version: '3'
services:
order:
restart: always
build: ./order
working_dir: /order
volumes:
- /tmp:/logs
expose:
- "8080"
try with this one
Dockerfile
FROM maven:alpine AS build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
FROM openjdk:alpine
COPY --from=build /home/app/target/*.jar /usr/local/lib/demo.jar
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]
if you get error like Can't execute jar- file: “no main manifest attribute”
replace last command
ENTRYPOINT ["java","-cp","/usr/local/lib/demo.jar","com.packagename.classnamewithoutextension"]

How can I start spring boot application in docker with profile?

I have a simple spring-boot project:
-resources
-application.yaml
-application-test.yaml
And I have this Dockerfile:
FROM openjdk:8-jdk-alpine
EXPOSE 8080
ADD micro-boot.jar micro-boot.jar
ENTRYPOINT ["java","-Dspring.profiles.active=test" "-jar","/micro-boot.jar"]
1) I build image - C:\micro-boot>docker build -f Dockerfile -t micro-boot .
2) show all images - C:\micro-boot>docker image ls -a
micro-boot latest ccc9a75ebc24 4 seconds ago 112MB
3) try to start C:\micro-boot>docker image ls -a
And I get an error:
/bin/sh: [java,-Dspring.profiles.active=test: not found
We have 3 ways:
1. Passing Spring Profile in a Dockerfile
FROM openjdk:8-jre-alpine
...
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom","-Dspring.profiles.active=test","-jar","app.jar"]
2. Passing Spring Profile in Docker run
docker run -d -p 8080:8080 -e "SPRING_PROFILES_ACTIVE=test" --name my-app:latest
3. Passing Spring Profile in DockerCompose
version: "3.5"
services:
my-app:
image: my-app:latest
ports:
- "8080:8080"
environment:
- "SPRING_PROFILES_ACTIVE=test"
There's a typo here
ENTRYPOINT ["java","-Dspring.profiles.active=test" comma missing here "-jar","/micro-boot.jar"]

How to copy files from other location into Docker image

I am trying to copy files from other location (in windows from D drive that is shared drive also) to my image.
But it is giving me error.
Step 5/8 : ADD ${APP_PATH}/${ARTIFACT}-${VERSION} /opt/tomcat/webapps/${ARTIFACT}-${VERSION}
ADD failed: stat /var/lib/docker/tmp/docker-builder990684261/d:/Application_Build/spring-tournament-portal-0.0.1-SNAPSHOT: no such file or directory
Scenario:
I am trying to make test,build,release phase cycle with the help of docker.
So My Multistage docker file's first version looked like this
FROM maven as build
WORKDIR /usr/local
RUN mkdir app
COPY . /usr/local/app/spring-tournament-portal/
WORKDIR /usr/local/app/spring-tournament-portal
RUN mvn -e package
FROM tomcat
ENV PORT 8080
ENV VERSION 0.0.1-SNAPSHOT
ENV ARTIFACT spring-tournament-portal
ENV JPDA_ADDRESS 8000
ENV JPDA_TRANSPORT dt_socket
COPY --from=build /usr/local/app/${ARTIFACT}/target/${ARTIFACT}-${VERSION} /usr/local/tomcat/webapps/${ARTIFACT}-${VERSION}
WORKDIR /usr/local/tomcat/bin
CMD ["catalina.sh jpda run"]
EXPOSE ${PORT}
But on every build maven fetches its dependency. So it was taking too much time.
So i made another approach. I created two docker files(One for build and other for release).
Over here the role of build docker file does is copy all source code into an image only. So that when i will create container, I could easily create volume for maven dependency to avoid redownloading:-
FROM indiver/tournament-base
RUN apt-get update && \
apt-get install -y \
-o APT::Install-Recommend=false -o APT::Install-Suggests=false \
maven
WORKDIR /usr/local
COPY . /spring-tournament-portal/
WORKDIR /spring-tournament-portal
COPY ./docker/dev/entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["sh", "/usr/local/bin/entrypoint.sh"]
RUN ["chmod", "+x", "/usr/local/bin/entrypoint.sh"]
Here is entrypoint.sh file
#!/bin/bash
echo "$#" Phase is executing.....
mvn clean "$#"
When i run the image after building docker file with the help of docker-compose.xml. I set volume for dependency folder.
Here is docker compose.xml
version: "2"
services:
test-service:
build:
context: ../../
dockerfile: ./docker/dev/Dockerfile
container_name: "test-service"
command: 'test'
volumes:
- .m2:/root/.m2
build-service:
build:
context: ../../
dockerfile: ./docker/dev/Dockerfile
container_name: "build-service"
command: 'package'
env_file:
- ./EnvironmentConstant.env
volumes:
- .m2:/root/.m2
database-service:
container_name: "database-service"
env_file:
- ./EnvironmentConstant.env
image: mysql
ports:
- "3306:3306"
volumes:
- ./dev-mysql:/var/lib/mysql
networks:
- app-network
networks:
app-network:
driver: bridge
So it does not need to redownload the dependency again that is in .m2 volume.
After that i need to create release image having content of build prepared by maven. But container of build service is already stopped. So i need to use docker cp command to get my prepared build.
docker cp build-service:/spring-tournament-portal/target/spring-tournament-portal-0.0.1-SNAPSHOT D:/Application_Build
Now i want build that is in Application_Build folder should be copied into my release image.
So my release docker file looks like
FROM indiver/tournament-release
ENV APP_PATH=d:/Application_Build
ENV ARTIFACT=spring-tournament-portal
ENV VERSION=0.0.1-SNAPSHOT
ADD ${APP_PATH}/${ARTIFACT}-${VERSION} /opt/tomcat/webapps/${ARTIFACT}-${VERSION}
WORKDIR /opt/tomcat/bin
ENTRYPOINT ["catalina.sh", "jpda", "run"]
EXPOSE ${PORT}
But As i have mentioned above it is giving me error
Step 5/8 : ADD ${APP_PATH}/${ARTIFACT}-${VERSION} /opt/tomcat/webapps/${ARTIFACT}-${VERSION} ADD failed: stat /var/lib/docker/tmp/docker-builder990684261/d:/Application_Build/spring-tournament-portal-0.0.1-SNAPSHOT: no such file or directory.
I tried to copy by COPY and ADD command. But nothing is working. How can i achieve this.
If It can be achieved this with the help of other relatively easy flow. It would be helpful as well.
The Dockerfile reference says:
ADD obeys the following rules:
The path must be inside the context of the build.
...
Overall your approach seems to be too complicated to me and a very non micro-services way of doing things.
I would suggest that you copy your dependencies into the binary that you are creating to create a self contained fat (uber) jar, which you can copy to the docker image, the way spring boot does.
You approach for having separate docker files for different environments is also problematic and could result in unexpected conditions in production.
So I too faced this similar problem .
You can try the below listed command and replace the Square brackets with your path:
"docker cp /[Your Source Directory] [ContainerId]:/[Destination Path]"

Categories

Resources