Can Spring Cloud Function be used with AWS Lambda base image - spring

I try to deploy a function on AWS Lambda by a container image, but I cannot find an example of how to build it with the AWS lambda base image. Does Spring Cloud Function support this deploy method or only support deploying by a jar?

I think what you are asking is closely related to AWS Custom Runtime and indeed we do have support and sample for it - https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-function-samples/function-sample-aws-custom

Yes, Spring Cloud Functions will work deployed as a container image. The process will be the same whether you use Spring Cloud Functions or another framework.
Here is an example Dockerfile from lambda-libs GitHub project.
# we'll use Amazon Linux 2 + Corretto 11 as our base
FROM public.ecr.aws/amazoncorretto/amazoncorretto:11 as base
# configure the build environment
FROM base as build
RUN yum install -y maven
WORKDIR /src
# cache and copy dependencies
ADD pom.xml .
RUN mvn dependency:go-offline dependency:copy-dependencies
# compile the function
ADD . .
RUN mvn package
# copy the function artifact and dependencies onto a clean base
FROM base
WORKDIR /function
COPY --from=build /src/target/dependency/*.jar ./
COPY --from=build /src/target/*.jar ./
# configure the runtime startup as main
ENTRYPOINT [ "/usr/bin/java", "-cp", "./*", "com.amazonaws.services.lambda.runtime.api.client.AWSLambda" ]
# pass the name of the function handler as an argument to the runtime
# in this case it'll be the special Spring Cloud Function handler
CMD [ "example.App::sayHello" ]

Related

My spring boot application was running fine but when I dockerized it I got File not Found error

I don't know what I'm getting this error when I dockerized my spring-boot application
this is my Dockerfile
enter image description here
First, I wonder is your application working on your IDE?
Second, I think you make sure to build and package.
It is not sure to exists a jar file in your target folder.
You always have to build and check by yourself.
Make the build process automatic.
How about using this Dockerfile?
FROM maven:3.8.6-openjdk-18-slim as MAVEN_BUILD
WORKDIR /build
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -Dmaven.test.skip=true
FROM openjdk:18-alpine
WORKDIR /app
ARG JAR_FILE=*.jar
COPY --from=MAVEN_BUILD /build/target/${JAR_FILE} ./app.jar
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
If maven or openjdk version not matched, check this site.
https://hub.docker.com/_/maven
https://hub.docker.com/_/openjdk
In your Spring Boot application, from what I can see your BookingController is missing. Make sure you have the file present and build your image accordingly.
For your Dockerfile, try to change add to ADD, as it seems your target files are not been copied into the image built.

Dockerfile for Spring boot

Spring docs tell me how to write a Dockerfile for my Spring Boot app. I adapted it to my gradle build with "build/libs" directory
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
But in my build/libs directory there are multiple versions of my jar:
app-22.9.0.jar
app-22.9.0-SNAPSHOT.jar
app-22.10.0.jar
app-22.10.0-SNAPSHOT.jar
...
Of course I can call 'gradle clean assemble' to do the job. But I need the Dockerfile in a test too. It is annoying to run clean assemble all the time.
How can I specify in my Dockerfile COPY command to use only the latest jar.
Docker uses normal shell glob rules when expanding patterns like this; there's no way to tell it to use the single most recent matching file, or the file with the largest embedded semantic version, or other things.
When you build the image, you can pass a more specific value for that ARG like
docker build --build-arg JAR_FILE=app-22.10.0.jar -t myapp:22.10.0 .
You may also want that build version to be in the image tag and it may be helpful to script this.
(You probably don't need to ./gradlew clean in between rebuilds, and that might make running ./gradlew assemble go faster.)

Dockerfile to create image of spring boot

I want to create Docker image for a spring boot application.It uses gardle as build tool.
In bitbucket repository i could see below files are placed
--> src
--> build.gradle
--> Dockerfile
--> gradlew
--> gradlew.bat
Now Dockerfile has below content
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
EXPOSE 8080
ENTRYPOINT ["java","-cp","app:app/lib/*","eds.billnq"]
When i try to create image using Dockerfile i get error
target/dependency/BOOT-INF library not found
target/dependency/META-INF library not found
My query is why here there is no gradle build steps in docker file ?
Also where target/dependency/ will be created ?
why here there is no gradle build steps in docker file ?
It looks like the Dockerfile is expecting the application to have already been built (by Gradle) before the Docker image is built, and for the resulting class files and jars to be available in various directories under target/dependency.
The Spring Boot Docker guide referred to by #WonChul Heo in the comments goes into how to build a Docker image using Gradle and specifically with the plugin gradle.plugin.com.palantir.gradle.docker:gradle-docker.
Also where target/dependency/ will be created ?
I'm guessing they should be created when you run your Gradle build, but without knowing more about how the build is configured, it's hard to say for sure.
I suggest you read through the guide again and compare what it recommends to what you have in your codebase, especially the Gradle build definitions.
At the end of the day, if you've pulled code from a private code repo and can't figure out how to make it build, it's probably best to seek out advice from the people who've committed to the codebase than from SO.
When working With Gradle ur jar file is going to be generated inside build/libs/{Your jar}
Can you please change ARG DEPENDENCY=target/dependency to ARG DEPENDENCY=build/libs and try? It will work.

Dockerfile that is used for building spring-cloud-dataflow-server image

I have downloaded the Spring cloud Dataflow server code from GitHub at https://github.com/spring-cloud/spring-cloud-dataflow. I am trying to understand how the docker image is build for this server. But I am unable to find dockerfile in this codebase.
Reference documentation section "Adding a Custom JDBC Driver" calls for modifying Pom.xml and rebuild with very little information. I need to use a custom jar and rebuild the image.
Already looked into this post https://github.com/spring-cloud/spring-cloud-dataflow/issues/2489 but I am trying to understand how the orginal image for Spring Dataflow server is built.
The Maven configuration to build the Spring Cloud Data Flow server is here
To build the docker image, you can run the following from your cloned repo (assuming you are on the latest):
./mvnw clean install -DskipTests
./mvnw docker:build -pl spring-cloud-dataflow-server
Thanks Gopinathan. I have used the below dockerfile instead of changing the POM.xml and rebuilding the docker image.
FROM mcr.microsoft.com/java/jdk:8u212-zulu-alpine as build
RUN apk add --update \
curl \
&& rm -rf /var/cache/apk/*
WORKDIR /workspace/app
RUN mkdir target
RUN curl -sS -o /workspace/app/target/spring-cloud-dataflow-server-2.1.2.RELEASE.jar https://repo.spring.io/release/org/springframework/cloud/spring-cloud-dataflow-server/2.1.2.RELEASE/spring-cloud-dataflow-server-2.1.2.RELEASE.jar
RUN curl -sS -o /workspace/app/target/mysql-connector-java-8.0.16.jar https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.16/mysql-connector-java-8.0.16.jar
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../spring-cloud-dataflow-server-2.1.2.RELEASE.jar)
RUN cp /workspace/app/target/mysql-connector-java-8.0.16.jar /workspace/app/target/dependency/BOOT-INF/lib/
FROM mcr.microsoft.com/java/jdk:8u212-zulu-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
RUN echo "$(ls -lR /app)"
ENTRYPOINT ["java","-cp","app:app/lib/*","org.springframework.cloud.dataflow.server.single.DataFlowServerApplication"]
dockerfile-from-image would help to reverse engineer from docker image.
Upvoted Ilyaperumal Gopinathan's answer, the best way is to build the project. The fabric8 maven docker plugin requires docker to be installed locally however - surely a lot of work to get to the 4 lines below.
This is the image produced by the 2.7.1 build -
FROM springcloud/baseimage:1.0.0
ENV LANG=C.UTF-8
COPY maven /
VOLUME ["/tmp"]
ENTRYPOINT ["java","-jar","/maven/spring-cloud-dataflow-server.jar"]
The spring cloud base image seems to be simply an Ubuntu base with Java 8 installed (https://github.com/spring-cloud/baseimage)?

Using Maven artifact in Google Cloud Docker build

I have a google cloud container build with the following steps
gcr.io/cloud-builders/mvn to run a mvn clean package cmd
gcr.io/cloud-builders/docker to create a docker image
My docker image includes and will run tomcat.
Both these steps work fine independently.
How can I copy the artifacts built by step 1 into the correct folder of my docker container? I need to move either the built wars or specific lib files from step 1 to the tomcat dir in my docker container.
Echoing out the /workspace and /root dir in my Dockerfile doesn't show the artifacts. I think I'm misunderstanding this relationship.
Thanks!
Edit:
I ended up changing the Dockerfile to set the WORKDIR to /workspace
and
COPY /{files built by maven} {target}
The working directory is a persistent volume mounted in the builder containers, by default under /workdir. You can find more details in the documentation here https://cloud.google.com/container-builder/docs/build-config#dir
I am not sure what is happening in your case. But there is an example with a Maven step and a Docker build step in the documentation of the gcr.io/cloud-builders/mvn builder. https://github.com/GoogleCloudPlatform/cloud-builders/tree/master/mvn/examples/spring_boot. I suggest you compare with your files.
If it does not help, could you share your Dockerfile and cloudbuild.yaml. Please make sure you remove any sensitive information.
Also, you can inspect the working directory by running the build locally https://cloud.google.com/container-builder/docs/build-debug-locally#preserve_intermediary_artifacts

Resources