CDK Docker Build
I imagine many developers use a Mac. If you use native-image to create a native binary, this binary won’t work on AWS Lambda (Amazon Linux 2). To solve this problem you can build the binary with a docker file, using Amazon Linux 2 (AL2) as the base.
I’ve built and published my own on dockerhub marksailes/al2graalvm.
The Dockerfile is available on GitHub marksailes/al2-graalvm, and I’d be very happy to receive pull requests. Docker isn’t something I’m particular deep with.
This image uses AL2 as the base and then adds GraalVM, native-image and maven.
The functionality within CDK is called BundlingOptions
. CDK puts our code into /asset-input
and
expects the output in /asset-output
. We change directory to our products
folder and run our
normal mvn clean install
with our native-image
profile.
Bundling options allows us to specify the image, which can be for a public repo like dockerhub.
We mount our local ~/.m2
folder to speed up builds.
List<String> functionOnePackagingInstructions = Arrays.asList(
"-c",
"cd products " +
"&& mvn clean install -P native-image "
+ "&& cp /asset-input/products/target/function.zip /asset-output/"
);
BundlingOptions.Builder builderOptions = BundlingOptions.builder()
.command(functionOnePackagingInstructions)
.image(DockerImage.fromRegistry("marksailes/al2-graalvm"))
.volumes(singletonList(
DockerVolume.builder()
.hostPath(System.getProperty("user.home") + "/.m2/")
.containerPath("/root/.m2/")
.build()
))
.user("root")
.outputType(ARCHIVED);
Our function changes in a number of ways. We move from a JAVA_11
runtime to PROVIDED_AL2
.
The code come from the docker output, and we can reduce the memory size.
Function productFunction = new Function(this, "ProductFunction", FunctionProps.builder()
.runtime(Runtime.PROVIDED_AL2)
.code(Code.fromAsset("../software/", AssetOptions.builder()
.bundling(builderOptions.build())
.build()))
.handler("com.graalvmonlambda.product.ProductRequestHandler")
.memorySize(256)
.logRetention(RetentionDays.ONE_WEEK)
.build());
Now when we do cdk deploy
, CDK will run our maven project within our docker image
produce a zip file with the bootstrap and native binary, then push this all to AWS.