Quarkus Building a Native Executable NoSuchFileException: /project - quarkus

I followed the steps from build quarkus native executable.
1.Bootstrapping the project:
mvn io.quarkus:quarkus-maven-plugin:0.11.0:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=getting-started \
-DclassName="org.acme.quickstart.GreetingResource" \
-Dpath="/hello"
2.Use docker in minishift
minishift start
eval $(minishift docker-env)
3.Generate package:
mvn package -Pnative -Dnative-image.docker-build=true
failed with the error trace below:
[INFO] [io.quarkus.creator.phase.nativeimage.NativeImagePhase] docker run -v /Users/.../quarkus/getting-started/target:/project:z --rm swd847/centos-graal-native-image-rc12 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -jar getting-started-1.0-SNAPSHOT-runner.jar -J-Djava.util.concurrent.ForkJoinPool.common.parallelism=1 -H:+PrintAnalysisCallTree -H:EnableURLProtocols=http -H:-SpawnIsolates -H:-JNI --no-server -H:-UseServiceLoaderFeature -H:+StackTrace
Error: Invalid Path entry getting-started-1.0-SNAPSHOT-runner.jar
Caused by: java.nio.file.NoSuchFileException: /project/getting-started-1.0-SNAPSHOT-runner.jar
As requested, the tree output is shown below:

The related Issue has been resolved at Quarkus github and remote container support is here.
Quoting the resolution comment:
Building native images using a remote docker daemon has been
implemented and merged for Quarkus 1.13 (PR #14635). Just use the flag
-Dquarkus.native.remote-container-build=true instead of
-Dquarkus.native.container-build=true.
So if you using minishift or minikube just use the
new option while building.

The -Dnative-image.docker-build=true feature of Quarkus will only work with the local docker daemon.
In your case you are using the Docker daemon from Minishift and the build files because the build artifacts are not present in the Minishift VM.
UPDATE
There is now a Quarkus issue that tracks this.

I think the best way is to combine the process of creating the application image and the actual compilation into one Dockerfile.
Your Dockerfile should contain 3 stages
build the java app
build the native image
build the final Docker image
First stage is for the fast fail if app has compilation issues ++ to build the jar file
Second stage is to produce native image from the jar + libs via native-image command or you can use "mvn -Pnative verify" if you are using an image which contains both maven and graalvm.
Third stage is to build the final Docker image based on the compiled native image and minimal base image such as alpine or fedora-minimal
An example of building the app ++ building the native image ++ building the final Docker image - https://github.com/quarkusio/quarkus-quickstarts/blob/master/getting-started-knative/Dockerfile

Related

Unable to create .exe using GraalVM docker image in Windows

In Windows 10 environment, with IntelliJ Idea, I have a sample Spring Boot application created with bootify, called Bootifytwo, which is located in the C:\CODIGO\IDEA_PROJECTS\bootifytwo folder.
In the pom.xml of said application I have the following dependency configured:
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
My intention is, using GraalVM, to get to generate the bootifytwo.exe and be able to run it correctly.
To do this, I have downloaded the following Docker image with GraalVM from the Oracle repositories; and performed the following commands:
docker pull container-registry.oracle.com/graalvm/community:ol8-java17-22.3.0-b1
docker images
docker run -it --rm container-registry.oracle.com/graalvm/community:ol8-java17-22.3.0-b1 bash
java -version
gu install native-image
native-image --version
Everything is working fine until I try to change to my project folder.
As long as I canĀ“t change to my project folder (cd C:\CODIGO\IDEA_PROJECTS\bootifytwo) I can't create the .exe with the following:
.\mvnw native:compile -Pnative
And finally locate myself in the target folder (cd C:\CODIGO\IDEA_PROJECTS\bootifytwo\target) and launch the desired bootifytwo.exe
I would appreciate help in this complex path. (I don't know if I need to define the GRAALVM_HOME variable, or map a volume...)
The solution to generate the .exe was:
Copy the app folder to (future) volume destination:
In my case:
C:\CODIGO\IDEA_PROJECTS\bootifytwo to C:\Volumenes-Docker\vol-graalvm-one\bootifytwo
Then launch the following commands:
docker run --name container-graalvm-one -v "C:\Volumenes-Docker\vol-graalvm-one:/app" -it container-registry.oracle.com/graalvm/community:ol8-java17-22.3.0-b1 bash
gu install native-image
cd bootifytwo
. ./mvnw native:compile -Pnative
Then, I was able to launch the app with:
./bootifytwo
But fails in the connection with my DB (that also was "inside" another docker/postgres container)

How to do maven build and run make command inside container

I need to run Maven build inside container and afterwards I need to run make command.
For executing Maven, I did the following inside dockerfile
FROM maven:3.8.1-adoptopenjdk-11 AS build
COPY src /usr/src/app/src
COPY pom.xml /usr/src/app
RUN mvn -f /usr/src/app/pom.xml clean package
After maven execution, some jar files are generated, which is needed to run make command (used in make file)
Now my question is how to get docker image for make, and how do I use it in same dockerfile? I tried to find docker image for make but didn't get it directly in dockerhub.
I'm familiar with building java code but not with building C/C++ code with make. Any help would be appreciated.

Building multi arch docker image with tags

Currently I have a spring application which was made to run on docker for which we have followed this documentation mentioned below:
https://spring.io/guides/gs/spring-boot-docker/
This I believe this command docker build -t springio/gs-spring-boot-docker . builds an image for x86 platform only.
As I'm using an x86 machine for development, how does one build a docker image for arm and x86 in dockerCLI? As I wanted an image than can run on a server(x86) and Rpi(arm) with the appropriate tags like:
org/app:x86
org/app:arm
You can do the builds by adding a build argument. For example:
docker build -t springio/gs-spring-boot-docker:arm32v7 --build-arg ARCH=arm32v7/ .
A easier way to build the image for all required platforms with one cli instruction is to use the experimental build engine buildx. See also instructions on the docker blog

How to Build & Push Container from docker-compose.ci.build.yml File

I am using ASP.NET Core and have used Visual Studio's Add Docker Support feature to get started. This adds a docker-compose.ci.build.yml file to my project which is supposed to be used on a CI server.
How do I build my Docker image from a compose file and push the image to my private Docker registry. I've tried the docker-compose build command:
docker-compose -f docker-compose.ci.build.yml build
However this outputs an error:
ci-build uses an image, skipping
I ran into a number of issues getting this to build initially. Fixes for me included updating Visual Studio 2017 to Update 4, updating the Visual Studio Tools for Docker extension, and updating/consolidating NuGet package references. In addition, in docker-compose.ci.build.yml I had to change the build image to microsoft/aspnetcore-build:1.0-2.0-stretch (see this GitHub issue for more details).
Assuming the docker-compose configurations are the same/similar to the default generated ones, try the following script:
$ docker-compose -f docker-compose.ci.build.yml up
$ docker-compose -f docker-compose.yml build
Bringing "up" docker-compose.ci.build.yml simply builds the project and then exits. The artifacts are published to the obj/Docker/publish folder. The "build" docker-compose.yml actually builds and tags the images using the artifacts from the obj/Docker/publish folder. I clean up at the end of my build script with the following:
$ docker-compose -f docker-compose.ci.build.yml down
For reference/inspiration-- This is working on a custom Linux build server and producing four Docker images from a single solution-- two ASP.NET Core apps and two .NET Core apps.
I managed to build docker container without docker-compose.ci.build.yml. I used .Net Core tasks to build and publish .Net Core app to "obj/Docker/publish" folder as dockerfile expects and then used docker-compose task to build the container and push it to private container repository.

Do not download all Maven dependencies on a Docker build

I'm trying to create a Dockerfile to then build a Maven project.
I wonder how to fix the Dockerfile and what command to then execute.
I would like to know how to run the build so that it does NOT download all the Maven dependencies every time it builds when the source code, sitting in the src/ directory, has NOT changed.
Here is my Dockerfile file:
FROM maven:3.3.9-jdk-8
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN cd /usr/src/app
ADD pom.xml /usr/src/app
RUN mvn dependency:resolve
ADD src /usr/src/app
RUN mvn package
ENTRYPOINT ["mvn"]
CMD ["package"]
Should I run the docker run --rm -it toolbox command or the docker build -t toolbox . command ?
Both of these above commands run fine, except that they both download all the Maven dependencies even if the source code has not been touched.
That's how Docker works. Every time you do docker run, it creates a new container which does not have any access to the files in the old container. So, it download all dependencies it requires. You can circumvent this by declaring an external volume. Looking at the Dockerfile of Maven, it declares a volume /root/.m2. So, you can use a directory in your host machine and attach it to this volume by -v option. Your Docker command would be,
`docker run -v <directory-in-your-host>:/root/.m2 <other-options-and-commands>
Every time you run a new docker run, Maven will look into your local directory before downloading the dependency.
However, my question is why don't you build your app first and use the resulting jar to create the docker images unless you have any specific reasons. You can create your own Dockerfile using java base image or simply use one of the docker-maven-plugin like spotify available out there. That makes your life a lot easier.

Resources