Deploy Java Lambda functions with container images
There are three ways to build a container image for a Java Lambda function:
-
Using an Amazon base image for Java
The Amazon base images are preloaded with a language runtime, a runtime interface client to manage the interaction between Lambda and your function code, and a runtime interface emulator for local testing.
-
Using an Amazon OS-only base image
Amazon OS-only base images
contain an Amazon Linux distribution and the runtime interface emulator . These images are commonly used to create container images for compiled languages, such as Go and Rust, and for a language or language version that Lambda doesn't provide a base image for, such as Node.js 19. You can also use OS-only base images to implement a custom runtime. To make the image compatible with Lambda, you must include the runtime interface client for Java in the image. -
You can use an alternative base image from another container registry, such as Alpine Linux or Debian. You can also use a custom image created by your organization. To make the image compatible with Lambda, you must include the runtime interface client for Java in the image.
Tip
To reduce the time it takes for Lambda container functions to become active, see Use multi-stage builds
This page explains how to build, test, and deploy container images for Lambda.
Topics
Amazon base images for Java
Amazon provides the following base images for Java:
| Tags | Runtime | Operating system | Dockerfile | Deprecation |
|---|---|---|---|---|
21 |
Java 21 | Amazon Linux 2023 | Dockerfile
for Java 21 on GitHub |
Jun 30, 2029 |
17 |
Java 17 | Amazon Linux 2 | Dockerfile
for Java 17 on GitHub |
Jun 30, 2026 |
11 |
Java 11 | Amazon Linux 2 | Dockerfile
for Java 11 on GitHub |
Jun 30, 2026 |
8.al2 |
Java 8 | Amazon Linux 2 | Dockerfile
for Java 8 on GitHub |
Jun 30, 2026 |
Amazon ECR repository: gallery.ecr.aws/lambda/java
The Java 21 and later base images are based on the Amazon Linux 2023 minimal container image. Earlier base images use Amazon Linux 2. AL2023 provides several advantages over Amazon Linux 2, including a smaller deployment footprint and updated versions of libraries such as glibc.
AL2023-based images use microdnf (symlinked as dnf) as the package manager instead of yum, which is the default package manager in Amazon Linux 2. microdnf is a standalone implementation of dnf. For a list of packages that are included in AL2023-based images, refer to the Minimal Container columns in Comparing packages installed on Amazon Linux 2023 Container Images. For more information about the differences between AL2023 and Amazon Linux 2, see Introducing the Amazon Linux 2023 runtime for Amazon Lambda
Note
To run AL2023-based images locally, including with Amazon Serverless Application Model (Amazon SAM), you must use Docker version 20.10.10 or later.
Using an Amazon base image for Java
To complete the steps in this section, you must have the following:
-
Java (for example, Amazon Corretto
) -
Docker
(minimum version 25.0.0) -
The Docker buildx plugin
.
-
Start the Docker image with the docker run command. In this example,
docker-imageis the image name andtestis the tag.docker run --platform linux/amd64 -p 9000:8080docker-image:testThis command runs the image as a container and creates a local endpoint at
localhost:9000/2015-03-31/functions/function/invocations.Note
If you built the Docker image for the ARM64 instruction set architecture, be sure to use the
--platform linux/option instead ofarm64--platform linux/.amd64 -
From a new terminal window, post an event to the local endpoint.
-
Get the container ID.
docker ps -
Use the docker kill
command to stop the container. In this command, replace 3766c4ab331cwith the container ID from the previous step.docker kill3766c4ab331c
To upload the image to Amazon ECR and create the Lambda function
-
Run the get-login-password
command to authenticate the Docker CLI to your Amazon ECR registry. -
Set the
--regionvalue to the Amazon Web Services Region where you want to create the Amazon ECR repository. -
Replace
111122223333with your Amazon Web Services account ID.
aws ecr get-login-password --regioncn-north-1| docker login --username AWS --password-stdin111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn -
-
Create a repository in Amazon ECR using the create-repository
command. aws ecr create-repository --repository-namehello-world--regioncn-north-1--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLENote
The Amazon ECR repository must be in the same Amazon Web Services Region as the Lambda function.
If successful, you see a response like this:
{ "repository": { "repositoryArn": "arn:aws-cn:ecr:cn-north-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } } -
Copy the
repositoryUrifrom the output in the previous step. -
Run the docker tag
command to tag your local image into your Amazon ECR repository as the latest version. In this command: -
docker-image:testis the name and tagof your Docker image. This is the image name and tag that you specified in the docker buildcommand. -
Replace
<ECRrepositoryUri>with therepositoryUrithat you copied. Make sure to include:latestat the end of the URI.
docker tag docker-image:test<ECRrepositoryUri>:latestExample:
docker tagdocker-image:test111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
-
Run the docker push
command to deploy your local image to the Amazon ECR repository. Make sure to include :latestat the end of the repository URI.docker push111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
Create an execution role for the function, if you don't already have one. You need the Amazon Resource Name (ARN) of the role in the next step.
-
Create the Lambda function. For
ImageUri, specify the repository URI from earlier. Make sure to include:latestat the end of the URI.aws lambda create-function \ --function-namehello-world\ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest \ --rolearn:aws-cn:iam::111122223333:role/lambda-exNote
You can create a function using an image in a different Amazon account, as long as the image is in the same Region as the Lambda function. For more information, see Amazon ECR cross-account permissions.
-
Invoke the function.
aws lambda invoke --function-namehello-worldresponse.jsonYou should see a response like this:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 } -
To see the output of the function, check the
response.jsonfile.
To update the function code, you must build the image again, upload the new image to the Amazon ECR repository, and then use the update-function-code
Lambda resolves the image tag to a specific image digest. This means that if you point the image tag that was used to deploy the function to a new image in Amazon ECR, Lambda doesn't automatically update the function to use the new image.
To deploy the new image to the same Lambda function, you must use the update-function-code--publish option creates a new version of the function using the updated container image.
aws lambda update-function-code \ --function-namehello-world\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest\ --publish
Using an alternative base image with the runtime interface client
If you use an OS-only base image or an alternative base image, you must include the runtime interface client in your image. The runtime interface client extends the Runtime API, which manages the interaction between Lambda and your function code.
Install the runtime interface client for Java in your Dockerfile, or as a dependency in your project. For example, to install the runtime interface client using the Maven package manager, add the following to your pom.xml file:
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-runtime-interface-client</artifactId> <version>2.3.2</version> </dependency>
For package details, see Amazon Lambda Java Runtime Interface Client
The following example demonstrates how to build a container image for Java using an Amazon Corretto image
To complete the steps in this section, you must have the following:
-
Java (for example, Amazon Corretto
) -
Docker
(minimum version 25.0.0) -
The Docker buildx plugin
.
-
Create a Maven project. The following parameters are required:
-
groupId – The full package namespace of your application.
-
artifactId – Your project name. This becomes the name of the directory for your project.
-
-
Open the project directory.
cdmyapp -
Open the
pom.xmlfile and replace the contents with the following. This file includes the aws-lambda-java-runtime-interface-clientas a dependency. Alternatively, you can install the runtime interface client in the Dockerfile. However, the simplest approach is to include the library as a dependency. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>example</groupId> <artifactId>hello-lambda</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>hello-lambda</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-runtime-interface-client</artifactId> <version>2.3.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>3.1.2</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> -
Open the
directory, and find themyapp/src/main/java/com/example/myappApp.javafile. This is the code for the Lambda function. Replace the code with the following.Example function handler
package example; public class App { public static String sayHello() { return "Hello world!"; } } -
The
mvn -B archetype:generatecommand from step 1 also generated a dummy test case in thesrc/testdirectory. For the purposes of this tutorial, skip over running tests by deleting this entire generated/testdirectory. -
Navigate back to the project's root directory, and then create a new Dockerfile. The following example Dockerfile uses an Amazon Corretto image
. Amazon Corretto is a no-cost, multiplatform, production-ready distribution of the OpenJDK. -
Set the
FROMproperty to the URI of the base image. -
Set the
ENTRYPOINTto the module that you want the Docker container to run when it starts. In this case, the module is the runtime interface client. -
Set the
CMDargument to the Lambda function handler.
Note that the example Dockerfile does not include a USER instruction
. When you deploy a container image to Lambda, Lambda automatically defines a default Linux user with least-privileged permissions. This is different from standard Docker behavior which defaults to the rootuser when noUSERinstruction is provided.Example Dockerfile
FROMpublic.ecr.aws/amazoncorretto/amazoncorretto:21as 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 ./ # Set runtime interface client as default command for the container runtime 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 CMD [ "example.App::sayHello" ] -
-
Build the Docker image with the docker build
command. The following example names the image docker-imageand gives it thetesttag. To make your image compatible with Lambda, you must use the --provenance=falseoption.docker buildx build --platform linux/amd64 --provenance=false -tdocker-image:test.Note
The command specifies the
--platform linux/amd64option to ensure that your container is compatible with the Lambda execution environment regardless of the architecture of your build machine. If you intend to create a Lambda function using the ARM64 instruction set architecture, be sure to change the command to use the--platform linux/arm64option instead.
Use the runtime interface emulator
To install and run the runtime interface emulator on your local machine
-
From your project directory, run the following command to download the runtime interface emulator (x86-64 architecture) from GitHub and install it on your local machine.
-
Start the Docker image with the docker run command. Note the following:
-
docker-imageis the image name andtestis the tag. -
/usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHellois theENTRYPOINTfollowed by theCMDfrom your Dockerfile.
This command runs the image as a container and creates a local endpoint at
localhost:9000/2015-03-31/functions/function/invocations.Note
If you built the Docker image for the ARM64 instruction set architecture, be sure to use the
--platform linux/option instead ofarm64--platform linux/.amd64 -
-
Post an event to the local endpoint.
-
Get the container ID.
docker ps -
Use the docker kill
command to stop the container. In this command, replace 3766c4ab331cwith the container ID from the previous step.docker kill3766c4ab331c
To upload the image to Amazon ECR and create the Lambda function
-
Run the get-login-password
command to authenticate the Docker CLI to your Amazon ECR registry. -
Set the
--regionvalue to the Amazon Web Services Region where you want to create the Amazon ECR repository. -
Replace
111122223333with your Amazon Web Services account ID.
aws ecr get-login-password --regioncn-north-1| docker login --username AWS --password-stdin111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn -
-
Create a repository in Amazon ECR using the create-repository
command. aws ecr create-repository --repository-namehello-world--regioncn-north-1--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLENote
The Amazon ECR repository must be in the same Amazon Web Services Region as the Lambda function.
If successful, you see a response like this:
{ "repository": { "repositoryArn": "arn:aws-cn:ecr:cn-north-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } } -
Copy the
repositoryUrifrom the output in the previous step. -
Run the docker tag
command to tag your local image into your Amazon ECR repository as the latest version. In this command: -
docker-image:testis the name and tagof your Docker image. This is the image name and tag that you specified in the docker buildcommand. -
Replace
<ECRrepositoryUri>with therepositoryUrithat you copied. Make sure to include:latestat the end of the URI.
docker tag docker-image:test<ECRrepositoryUri>:latestExample:
docker tagdocker-image:test111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
-
Run the docker push
command to deploy your local image to the Amazon ECR repository. Make sure to include :latestat the end of the repository URI.docker push111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest -
Create an execution role for the function, if you don't already have one. You need the Amazon Resource Name (ARN) of the role in the next step.
-
Create the Lambda function. For
ImageUri, specify the repository URI from earlier. Make sure to include:latestat the end of the URI.aws lambda create-function \ --function-namehello-world\ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest \ --rolearn:aws-cn:iam::111122223333:role/lambda-exNote
You can create a function using an image in a different Amazon account, as long as the image is in the same Region as the Lambda function. For more information, see Amazon ECR cross-account permissions.
-
Invoke the function.
aws lambda invoke --function-namehello-worldresponse.jsonYou should see a response like this:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 } -
To see the output of the function, check the
response.jsonfile.
To update the function code, you must build the image again, upload the new image to the Amazon ECR repository, and then use the update-function-code
Lambda resolves the image tag to a specific image digest. This means that if you point the image tag that was used to deploy the function to a new image in Amazon ECR, Lambda doesn't automatically update the function to use the new image.
To deploy the new image to the same Lambda function, you must use the update-function-code--publish option creates a new version of the function using the updated container image.
aws lambda update-function-code \ --function-namehello-world\ --image-uri111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest\ --publish