diff --git a/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec.yaml b/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec.yaml index 1e81ccffe..a295e97db 100644 --- a/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec.yaml +++ b/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec.yaml @@ -14,6 +14,7 @@ steps: command: | docker build -t ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME} . docker tag ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:latest ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:$buildId + outputArtifacts: - name: image-jvm type: DOCKER_IMAGE diff --git a/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec_native.yaml b/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec_native.yaml index eb936c36f..fda390cb5 100644 --- a/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec_native.yaml +++ b/app-dev/devops-and-containers/devops/oci-devops-terraform-function-java-graalvm/files/build_pipeline_specs/build_spec_native.yaml @@ -3,17 +3,45 @@ component: build timeoutInSeconds: 5000 shell: bash env: + variables: + "JAVA_HOME" : "/usr/lib64/graalvm/graalvm-java23" exportedVariables: - buildId +# https://docs.oracle.com/en/graalvm/jdk/23/docs/getting-started/oci/devops-build-pipeline/#prerequisites steps: - type: Command command: | buildId=`echo ${OCI_BUILD_RUN_ID} | rev | cut -c 1-6 | rev` echo "Build ID: $buildId" + - type: Command + command: | + yum -y install graalvm-23-native-image + - type: Command + command: | + export PATH=$JAVA_HOME/bin:$PATH + - type: Command + command: | + mvn package + - type: Command + command: | + native-image \ + -H:ReflectionConfigurationFiles=reflection.json \ + -Ob \ + -H:Name=Hello \ + -cp "target/Hellofunc-1.0-SNAPSHOT-jar-with-dependencies.jar" \ + com.fnproject.fn.runtime.EntryPoint - type: Command command: | docker build -f Dockerfile.native -t ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME} . docker tag ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:latest ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:$buildId + # Alternate (faster) method of pushing if don't want to wait outputArtifacts getting executed (stage can be removed from build pipeline) + # This does not require personal Docker credentials (!) + - type: Command + command: | + yum install jq -y + oci raw-request --region eu-frankfurt-1 --http-method GET --target-uri 'https://fra.ocir.io/20180419/docker/token' --auth=resource_principal | jq -r .data.token | docker login -u BEARER_TOKEN --password-stdin fra.ocir.io + docker push ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:$buildId + outputArtifacts: - name: image-native type: DOCKER_IMAGE diff --git a/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/README.md b/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/README.md index 5d708946e..4baf112b2 100644 --- a/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/README.md +++ b/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/README.md @@ -116,39 +116,18 @@ GraalVM compiles your Java functions ahead of time into standalone binaries that

-To do this a Docker multi-stage build is used. - +To do this a create OCI DevOps project for a Function CI/CD and then clone the repo and copy the following files with the Function source and commit and push them to the repo:

- -Before building the native image let's do a full maven build for the project to create the necessary libraries under target/lib: - -

-mvn clean install
-
- -Then build the Docker container using multi-stage Docker file including the GraalVM native image compilation: - -
-docker build -f Dockerfile.native -t fra.ocir.io/<YOUR OCI TENANCY NAMESPACE>/helloworldai-java:2 .
-
- -The GraalVM compilation stage requires quite a bit resources from your localhost so in case for example using Rancher desktop -think of increasing the CPU and memory for it to make the build faster. - +

- -In the Dockerfile.native two things are important: Including the reflection.json with the proper function class name and passing Fn FDK libraries with "-Djava.library.path=/lib" in the container CMD along with the "com.example.HelloAIFunction::handleRequest" function handler. - +After pushing run the native build pipeline and test the Function in cloud shell.

-After the build push the container to OCIR repo: - -

-docker push fra.ocir.io/<YOUR OCI TENANCY NAMESPACE>/helloworldai-java:2
-
- -Finally deploy the container to your OCI Function by replacing the container using the Cloud UI by editing the function and changing the container from helloworldai-java:1 to helloworldai-java:2. Then test it. - # Useful Links diff --git a/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/Dockerfile.native b/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/Dockerfile.native index 3f01a6d7b..c5a8da4f1 100644 --- a/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/Dockerfile.native +++ b/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/Dockerfile.native @@ -1,27 +1,4 @@ -FROM fnproject/fn-java-fdk-build:jdk17-1.0-latest as build-stage -WORKDIR /function -ENV MAVEN_OPTS -Dhttp.proxyHost= -Dhttp.proxyPort= -Dhttps.proxyHost= -Dhttps.proxyPort= -Dhttp.nonProxyHosts= -Dmaven.repo.local=/usr/share/maven/ref/repository -ADD pom.xml /function/pom.xml -RUN ["mvn", "package", "dependency:copy-dependencies", "-DincludeScope=runtime", "-DskipTests=true", "-Dmdep.prependGroupId=true", "-DoutputDirectory=target", "--fail-never"] -ADD src /function/src -RUN ["mvn", "package"] - -FROM container-registry.oracle.com/graalvm/native-image:23-ol8 AS native -WORKDIR /app -COPY --from=build-stage /function/target . -ADD reflection.json . - -RUN native-image \ - -H:ReflectionConfigurationFiles=/app/reflection.json \ - -Ob \ - -H:Name=Hello \ - -cp "/app/Hellofunc-1.0-SNAPSHOT.jar:/app/*" \ - com.fnproject.fn.runtime.EntryPoint - -FROM fnproject/fn-java-fdk:jre17-latest as fdk - -FROM container-registry.oracle.com/os/oraclelinux:8-slim -COPY --from=native /app/Hello . -COPY --from=fdk /function/runtime/* ./ +FROM fnproject/fn-java-fdk:jre17-latest +COPY Hello ./ ENTRYPOINT [ "./Hello" ] -CMD [ "com.example.fn.HelloFunction::handleRequest", "-Djava.library.path=/lib"] \ No newline at end of file +CMD [ "com.example.fn.HelloFunction::handleRequest", "-Djava.library.path=/function/runtime/lib"] \ No newline at end of file diff --git a/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/build_spec_native.yaml b/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/build_spec_native.yaml index eb936c36f..fda390cb5 100644 --- a/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/build_spec_native.yaml +++ b/app-dev/devops-and-containers/functions/java-helloworld-AI-with-local-dev-and-oci-functions/files/build_spec_native.yaml @@ -3,17 +3,45 @@ component: build timeoutInSeconds: 5000 shell: bash env: + variables: + "JAVA_HOME" : "/usr/lib64/graalvm/graalvm-java23" exportedVariables: - buildId +# https://docs.oracle.com/en/graalvm/jdk/23/docs/getting-started/oci/devops-build-pipeline/#prerequisites steps: - type: Command command: | buildId=`echo ${OCI_BUILD_RUN_ID} | rev | cut -c 1-6 | rev` echo "Build ID: $buildId" + - type: Command + command: | + yum -y install graalvm-23-native-image + - type: Command + command: | + export PATH=$JAVA_HOME/bin:$PATH + - type: Command + command: | + mvn package + - type: Command + command: | + native-image \ + -H:ReflectionConfigurationFiles=reflection.json \ + -Ob \ + -H:Name=Hello \ + -cp "target/Hellofunc-1.0-SNAPSHOT-jar-with-dependencies.jar" \ + com.fnproject.fn.runtime.EntryPoint - type: Command command: | docker build -f Dockerfile.native -t ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME} . docker tag ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:latest ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:$buildId + # Alternate (faster) method of pushing if don't want to wait outputArtifacts getting executed (stage can be removed from build pipeline) + # This does not require personal Docker credentials (!) + - type: Command + command: | + yum install jq -y + oci raw-request --region eu-frankfurt-1 --http-method GET --target-uri 'https://fra.ocir.io/20180419/docker/token' --auth=resource_principal | jq -r .data.token | docker login -u BEARER_TOKEN --password-stdin fra.ocir.io + docker push ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:$buildId + outputArtifacts: - name: image-native type: DOCKER_IMAGE