Create a Lambda Container Image based on Java 15

Overview

AWS Lambda now supports container images (https://aws.amazon.com/jp/blogs/news/new-for-aws-lambda-container-image-support/).

It is quick and easy to use Base image provided by AWS to create a container image. However, as of January 15, 2021, Java 15 is not available.

The project I'm involved in is currently using Java 15 and ** 11 is a lot of trouble, so make a container image based on 15! ** Said, I thought it would be impossible for me ... I did some research and it worked, so I'll share it.

Source code

I will publish the source code as a deliverable immediately. I think it will work.

This is a sample that just returns 200 OK. intx24/java-15-lambda-container

Most of the Handler processing is borrowed from sample of awsdocs/aws-lambda-developer-guide. As a change, an unnecessary switch expression was added to confirm Java 15 compatibility.

How did you do

1. First try running with Java 11 base image

Based on the Java 11 base image, let's move it first.

Thankfully, there was a related article, so I used it as a reference and created a Java 11-based Lambda image. I tried AWS Lambda container support in Java.

2. Take a look at the Java 11 base image Dockerfile

My boss said, "Let's refer to Dockerfile of Java 11 base image", so let's take a look.

You can see that we are ADDing a lot of tar.xz that we don't understand. You can unpack the tar.xz file by doing git lfs pull. (At first I didn't understand this and thought I was stuck) Below, I will write what I understood

lambda-entrypoint.sh

ENTRY POINT of Dockerfile.

Apparently / var/runtime/bootstrap is executed. If there is no $ {AWS_LAMBDA_RUNTIME_API} (probably in a local environment), it seems that the emulator can be used to enable local execution.

For the emulator, see Runtime support for Lambda container images ](Https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/runtimes-images.html#runtimes-api-client), so you can copy this to the container locally. is.

lambda-entrypoint.sh


#!/bin/sh
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.

if [ $# -ne 1 ]; then
  echo "entrypoint requires the handler name to be the first argument" 1>&2
  exit 142
fi
export _HANDLER="$1"

RUNTIME_ENTRYPOINT=/var/runtime/bootstrap
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
  exec /usr/local/bin/aws-lambda-rie $RUNTIME_ENTRYPOINT
else
  exec $RUNTIME_ENTRYPOINT
fi

/var/runtime/bootstrap It was a file I didn't understand. It didn't work when I copied and pasted it into a container & I decided that the contents were too black box, so I will look for an alternative. Apparently you can create bootstrap by following the steps to create a custom runtime?

When I was researching the custom runtime and decided to give up because it was impossible, I found out that I can execute Lambda function with aws-lambda-java-runtime-interface-client. It seems that this command should be used as an argument of aws-lambda-rie.

3. Try to implement

Dockerfile

I have an image of Amazon Linux 2 with Java 15, so I will base it on this. Using your own lambda-entrypoint.sh as ENTRYPOINT, which will be described later, Pass the Lambda function example.Handler :: handleRequest.

FROM amazoncorretto:15

# set environment variables
ENV CLASSPATH /var/task/*

WORKDIR /var/task

# copy lambda execution files
COPY aws-lambda-rie /usr/local/bin/aws-lambda-rie
COPY lambda-entrypoint.sh /lambda-entrypoint.sh

# Copy function code
COPY build/libs/java-15-lambda-container-1.0-SNAPSHOT-all.jar /var/task/

# Set the Entrypoint
ENTRYPOINT ["/lambda-entrypoint.sh"]

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "example.Handler::handleRequest" ]

lambda-entrypoint.sh

Run aws-lambda-java-runtime-interface-client. The Lambda function specified in CMD in the Dockerfile is passed to $ HANDLER_NAME.

Pass java -cp ./* com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App :: sayHello as an argument according to the README of aws-lambda-java-runtime-interface-client When, Replace aws-lambda-rie with/usr/bin/java because it will interpret java as the path with bootstrap and die.

Also, here the classpath has already been specified as an environment variable in the Dockerfile.

#!/bin/sh

if [ $# -ne 1 ]; then
  echo "entrypoint requires the handler name to be the first argument" 1>&2
  exit 142
fi

HANDLER_NAME=$1

if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
  # local environment
  exec /usr/local/bin/aws-lambda-rie \
    /usr/bin/java \
    com.amazonaws.services.lambda.runtime.api.client.AWSLambda "$HANDLER_NAME"
else
  exec /usr/bin/java \
    com.amazonaws.services.lambda.runtime.api.client.AWSLambda "$HANDLER_NAME"
fi

/var/runtime/bootstrap It's no longer needed because it's integrated into lambda-entrypoint.sh.

What I had a hard time

I don't know about java build

I had about a year of experience with java itself + I was touching it via intelliJ + I was a person who participated in a prototype project on the way java was recognized to work for the time being when the gradle task was executed.

I didn't even know that it couldn't be executed without passing through the classpath in the first place, and I was exhausted for about half a day with the Class Not Found error. For the same reason, I gave up on building a custom runtime in a minute.

Unable to explore AWS-supplied base image with run -it option

At first I didn't even know the concept of ENTRYPOINT, so When I tried to search the container with run -it to check various files, I was in trouble. As a result, you can do cat via docker exec, I checked it in the Files tab of IntelliJ docker.

Summary

This time, I made a Lambda Container Image based on Java 15, and I was able to get it to work.

I spent about 4 days working on it, including investigation and implementation. It was an experience that I thought there was still much to know.

Recommended Posts

Create a Lambda Container Image based on Java 15
How to create a lightweight container image for Java apps
How to deploy a container on AWS Lambda
[Java] Create a filter
Lambda on Terraform Container
Created a Docker container image for an OpenLDAP server based on Fedora
Create a Java development environment using jenv on Mac
Create a docker image that runs a simple Java app
Let's create a gcloud development environment on a centos8 container
Create a java method [Memo] [java11]
[Java] Create a temporary file
Create a Java (Gradle) project with VS Code and develop it on a Docker container
Create a Java (Maven) project with VS Code and develop it on a Docker container
Create a SlackBot with AWS lambda & API Gateway in Java
Try Hello World using plain Java on a Docker container
Create a Kibana container image for ARM64 (Raspberry Pi/Mac M1)
Create a lightweight STNS Docker image
How to make a Java container
Run React on a Docker container
Is Java on AWS Lambda slow?
Hello World on AWS Lambda + Java
Create a Java project using Eclipse
[Java] How to create a folder
Run PureScript on a Docker container
Java9 (based on Oracle JVM) catchup
What is a lambda expression (Java)
I made a Ruby container image and moved the Lambda function
I tried deploying a Docker container on Lambda with Serverless Framework
Create a Docker Image for redoc-cli and register it on Docker Hub
[Java] Create and apply a slide master
Access MySQL on a Docker container from a local (host OS) Java program
[Java] Stepping on a JDK compiler bug
Let's create a Java development environment (updating)
Create a TODO app in Java 7 Create Header
Build a Java development environment on Mac
Try building a GPU container on GCP.
Deploy a Java web app on Heroku
Volume of trying to create a Java Web application on Windows Server 2016
Docker Compact Manual (4: Create a custom image)
Create a Docker container for your development web server in Ansible on MacOS
I want to play a GIF image on the Andorid app (Java, Kotlin)
Create a CSR with extended information in Java
[Windows] [IntelliJ] [Java] [Tomcat] Create a Tomcat9 environment with IntelliJ
Let's create a timed process with Java Timer! !!
[Java] Create something like a product search API
Deserialize CSV in Java based on header name
Try to create a bulletin board in Java
[Java] Create a collection with only one element
Let's create a super-simple web framework in Java
[Java] Let's create a mod for Minecraft 1.14.4 [Introduction]
Create Scala Seq from Java, make Scala Seq a Java List
[Java] Let's create a mod for Minecraft 1.16.1 [Introduction]
Update container image with KUSANAGI Runs on Docker
I tried running Ansible on a Docker container
[Java] Let's create a mod for Minecraft 1.14.4 [99. Mod output]
Build a Java runtime environment on Sakura VPS
I tried running Java on a Mac terminal
Hello Java Lambda
[Java] Lambda expression
Java lambda expression
[Java] Let's create a mod for Minecraft 1.14.4 [0. Basic file]