I'm building Docker image to run Spring Boot, but while building it i get error about copying jar file from target directory:
failed to solve: lstat /var/lib/docker/tmp/buildkit-mount188888512/var/www/app/target: no such file or directory
Here's the backend.Dockerfile:
FROM openjdk:17
WORKDIR /var/www/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw package -Dmaven.test.skip
EXPOSE 8080
COPY var/www/app/target/*.jar app.jar
CMD ["java", "-jar", "app.jar"]
Here's the part of docker-compose.yaml responsible for SpringBoot container:
app:
container_name: app
build:
dockerfile: ./docker/backend.Dockerfile
restart: on-failure
ports:
- "8080:8080"
depends_on:
- mysql
- mail-catcher
And the project structure:
.
├── docker
│ └── backend.Dockerfile
├── src
│ └──...
├── target
│ └──...
├── mvnw
├── mvnw.cmd
├── pom.xml
└── docker-compose.yaml
I would recommend another way of building your docker images with Spring Boot Project.
You can refer to this example by using the maven plugin during the maven build, your image will be built. The plugin comes from org.springframework.boot and it will help you build the image for the required module. You would need to use it in your pom.xml file if it is a maven project.
Then you could just run 'mvn clean install' if you have any test that you want to be run as well, or if you want your tests to be skipped you can use 'mvn clean install -DskipTests'
The image will be built in a layered format of docker, in a multistage image build format.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>ms/product.service:latest</name>
</image>
</configuration>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>build-image</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Related
I'm trying to create my first "native java app" using spring-native. I modify my pom adding this
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>0.10.5</version>
</dependency>
and this ( in the plugin part )
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
If I run "mvn clean package" everythng works fine; but when I try "spring-boot:build-image" I get this error (the part of the picture that you can't see says "x509: certificate signed by unknown authority"):
I already tried to add to intellij the certs (image below) of the site but I get the same error.
Any suggestion?
The attempt to download from https://github.com/graalvm/graalvm-ce-builds/releases is happening inside a Docker container that runs the Cloud Native Buildpacks builder and buildpacks. Certificate errors like this can happen when the Docker container is behind a corporate HTTP proxy that uses custom CA certificates. There is a Paketo buildpacks issue and a Spring Boot issue that cover similar errors.
Adding certificates to a JDK trust store will not fix the issue. Certificates must be provided to the builder container when it is launched. This is covered in the Paketo documentation and in the Spring Boot documentation, but it is a little difficult to understand exactly how to configure certificates.
As an example:
First create a bindings directory in the root of your project structure (at the same level as the project src directory) and copy the custom certificate to that directory (where my-custom-certificate.crt is a CA certificate in PEM format):
$ mkdir -p bindings/certificates
$ echo "ca-certificates" > bindings/certificates/type
$ cp /some/path/to/my-custom-certificate.crt bindings/certificates/my-custom-certificate.crt
$ tree bindings
bindings
├── certificates
│ ├── my-custom-certificate.crt
│ └── type
Then configure the Spring Boot Maven plugin to provide the binding to the Paketo CNB builder when the image is built:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
<bindings>
<binding>${basedir}/bindings/certificates:/platform/bindings/ca-certificates</binding>
</bindings>
</image>
</configuration>
</plugin>
Note that the bindings configuration of the Spring Boot Maven plugin requires Spring Boot version 2.5.0 or greater.
I'm starting working with docker and I'm trying to dockerize my Spring boot Application. I generated this using spring initializr. I'm working with maven. My DockerFile looks like this:
FROM java:8-jdk-alpine
COPY ${JAR_FILE} app.jar
WORKDIR /usr/app
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
It's pretty simple.
I executed the next commands:
docker build -t shortenurl .
I can see the image in the console with docker images:
But when I try to run the image with the command: docker run -p 8080:8080 shortenurl I got this error message: Error: Invalid or corrupt jarfile /app.jar
I've tried different configurations but not pretty sure. Any advice?
Thanks.
This is my plugin pom.xml plugins section:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.2.3</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
This is my log after the command:docker build -t shortenurl .
$ docker build -t shortenurl .
Sending build context to Docker daemon 32.89MB
Step 1/5 : FROM java:8-jdk-alpine
---> 3fd9dd82815c
Step 2/5 : COPY ${JAR_FILE} app.jar
---> 248aa4be697d
Step 3/5 : WORKDIR /usr/app
---> Running in 5fcd71c548af
Removing intermediate container 5fcd71c548af
---> bc344b970b11
Step 4/5 : EXPOSE 8080
---> Running in 46b4e4f8e9b7
Removing intermediate container 46b4e4f8e9b7
---> 6b4f55a86a23
Step 5/5 : ENTRYPOINT ["java","-jar","/app.jar"]
---> Running in 838a6052f4c8
Removing intermediate container 838a6052f4c8
---> 7d7d272ea42d
Successfully built 7d7d272ea42d
Successfully tagged shortenurl:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
You're building with spring-boot-maven-plugin but you're not generating an executable jar. Update your plugin's configuration to:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
and you should be fine.
I using jenkins spring boot and docker in my app. I want deploy spring boot in jenkin and put jar when deploy into docker and start it automatic. I reference to here :
https://denisdbell.wordpress.com/2017/08/26/automated-deployment-jenkins-docker-spring-boot/
But i have a problem. It deploy success but don't run jar in docker. When i type docker - ps it show me jar and i must run it manually. I want when jenkin deploy it automatic put images into docker and run it automatic.
I have two question:
- In my project spring boot, i need put docker in root project ?
- How to jenkin deploy and put images to docker and run automatic jar when jenkin deploy
- When i have mutiple modules, how to i specific copy only jar modules i need deploy and copy to docker and run it.
Thanks you so much help me
Question 1:- Yes you need to add it to the root folder.
Question 2:- You have to use the dockerfile-maven-plugin to push/pull images and use the shell commands from Jenkins to run the same.
Add the SCM GIT, Stash, Hg as this
<scm>
<connection>scm:git:ssh://git#guthub.com/yourproject.git</connection>
<developerConnection>scm:git:ssh://git#guthub.com/yourproject.git[push=]scm:git:ssh://git#guthub.com/yourproject.git</developerConnection>
<tag>HEAD</tag>
</scm>
Add the plugin as
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.3</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>${docker.image.prefix}/yourproject-${project.artifactId}
</repository>
<tag>${project.version}</tag>
</configuration>
In this while building your jar pass the arguments
mvn clean install -DskiptTests -Ddocker.image.prefix=<your docker repo url>
This command would automatically push the latest project version docker image to the repository.
Use the Shell commands to fetch this image and start the docker from the shell.
Testing the cloud-build
Part of my cloudbuild.yaml
- name: 'gcr.io/cloud-builders/mvn'
args: ['dockerfile:build']
dockerfile:build perfectly works in bitbucket pipeline, no problem. I use
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven-version}</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>gcr.io/my-project-id/${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
But with the cloud-build for this single step I get the error:
[INFO] Step 14/15 : ARG JAR_FILE
[INFO]
[INFO] ---> Using cache
[INFO] ---> 55793de4bb9f
[INFO] [INFO] Step 15/15 : ADD target/${JAR_FILE} /usr/share/$SERVCE_FOLDER_NAME/app.jar
[INFO]
[ERROR] ADD failed: stat /mnt/cache/docker/tmp/docker-builder589658449/target/myappname-0.0.1-SNAPSHOT.jar: no such file or directory
(the JAR_FILE is passed from the maven dockerfile plugin
no such file or directory
Why?.. In the end of the day I juse call dockerfile:build and expect it to be the same as it is when I build it from another pipeline.
My Dockerfile:
FROM openjdk:8-jdk
ENV GOOGLE_APPLICATION_CREDENTIALS=/app/credentials.json
ARG ACTIVE_PROFILES=dev
ENV ACTIVE_PROFILES=$ACTIVE_PROFILES
ARG CREDENTIALS
ARG SERVCE_FOLDER_NAME=myappname-service
ENV SERVCE_FOLDER_NAME=$SERVCE_FOLDER_NAME
#ENTRYPOINT ["/usr/bin/java", "-jar", "/usr/share/$SERVCE_FOLDER_NAME/app.jar"]
ENTRYPOINT ["./entrypoint.sh" ]
WORKDIR /app
EXPOSE 8080
COPY ./.gcloud/credentials.json credentials.json
COPY entrypoint.sh .
#Add Maven dependencies (not shaded into the artifact; Docker-cached)
#ADD target/lib /usr/share/$SERVCE_FOLDER_NAME/lib
ARG JAR_FILE
ADD target/${JAR_FILE} /usr/share/$SERVCE_FOLDER_NAME/app.jar
EntryPoint script is (that is what is mentioned on step 15/15 in the log):
java -Djava.security.egd=file:/dev/./urandom -jar /usr/share/$SERVCE_FOLDER_NAME/app.jar --spring.profiles.active=$ACTIVE_PROFILES
(I did try to pass hard-coded values to $SERVCE_FOLDER_NAME, $ACTIVE_PROFILES - same [it works in bitbucket pipeline])
A few things come to mind,
how are you triggering the builds?
manually with gcloud or api? or automatically with build triggers or the github app?
it seems that the target/ directory might not be present in the remote workspace-- are you ignoring target/ or .jar files anywhere?
the remote workspace might not be getting the target/ directory or .jar files if they are in your .gitignore or .gcloudignore
try making an empty .gcloudignore or temporarily removing target/ and .jar files from .gitignore
relevant links: https://cloud.google.com/sdk/gcloud/reference/topic/gcloudignore, https://github.com/GoogleCloudPlatform/cloud-builders/issues/40
have you tried debugging with cloud-build-local? it allows you to write and explore the workspace locally
https://cloud.google.com/cloud-build/docs/build-debug-locally
https://github.com/GoogleCloudPlatform/cloud-build-local
I'm using spring boot and am trying to set it up with Docker. I've tried everything I could find on google and nothing seems to get me going. I'm running
mvn clean package docker:build
Running this will do the spring-boot tests, run DB migrations, build the JAR, and then when it comes to Building the Docker image, I get the following error:
Failed to execute goal com.spotify:docker-maven-plugin:0.4.9:build (default-cli)
on project app: Exception caught: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target -> [Help 1]
Here is the Dockerfile I'm using:
FROM java:8-jdk
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/james/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
EXPOSE 8080
VOLUME /tmp
ADD app-0.0.1-SNAPSHOT.jar app.jar
RUN sh -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
And here is my docker-maven-plugin configuration:
... pom stuff
<docker.image.prefix>jamesone1</docker.image.prefix>
... other pom stufff
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.9</version>
<configuration>
<dockerHost>https://192.168.99.100:2376</dockerHost>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
I'm using the dock for mac & am using a docker-machine with the following env:
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/james/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
What's going on?! Am I missing something?
fixed this in windows 10 by:
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<imageName>yourImageName</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<dockerHost>https://192.168.99.100:2376</dockerHost>
<dockerCertPath>/Users/your_user/.docker/machine/machines/default</dockerCertPath>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
Important are these two tags:
<dockerHost>https://192.168.99.100:2376</dockerHost>
<dockerCertPath>/Users/your_user/.docker/machine/machines/default</dockerCertPath>
I am using a dockerfile, which path you have to define with this tag:
<dockerDirectory>src/main/docker</dockerDirectory>
Now you can build your jar and generate docker image via:
mvn package docker:build
I think on mac just follwing value has to be different:
<dockerCertPath>/Users/your_user/.docker/machine/machines/default</dockerCertPath>
I ended up building the docker image by myself without the plugin:
docker build -f Dockefile .
And my Dockefile (has been renamed):
FROM java:8-jdk
EXPOSE 8080
#VOLUME /tmp
ADD target/app-0.0.1-SNAPSHOT.jar /opt/demo/app-0.0.1-SNAPSHOT.jar
CMD ["java","-jar","/opt/demo/app-0.0.1-SNAPSHOT.jar"]
I then run it like so:
docker run <container id here>
I just couldn't get the mvn plugin to work!
Edit
Furthermore I ended up creating a docker-compose.yml which makes things a lot simpler!!!
You define properties such as the ports you want open, dockerfile location, and run docker-compose, and it'll magically build+run the docker image!
Example docker-compose.yml that I'm using:
version: '2'
services:
web:
build: .
ports:
- "8080:8080"
build references the Dockerfile location. *Note you may need to the Dockerfile+yml file to be in the same location!
ports reference the ports I want open. Now I can goto localhost:8080 and my request will be forwarded to the docker container.
Read more on docker container here:
https://docs.docker.com/compose/gettingstarted/