Deploy Ruby Lambda functions with container images - Amazon Lambda
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China (PDF).

Deploy Ruby Lambda functions with container images

There are three ways to build a container image for a Ruby Lambda function:

Tip

To reduce the time it takes for Lambda container functions to become active, see Use multi-stage builds in the Docker documentation. To build efficient container images, follow the Best practices for writing Dockerfiles.

This page explains how to build, test, and deploy container images for Lambda.

Amazon base images for Ruby

Amazon provides the following base images for Ruby:

Tags Runtime Operating system Dockerfile Deprecation

3.2

Ruby 3.2 Amazon Linux 2 Dockerfile for Ruby 3.2 on GitHub

2.7

Ruby 2.7 Amazon Linux 2 Dockerfile for Ruby 2.7 on GitHub

Dec 7, 2023

Amazon ECR repository: gallery.ecr.aws/lambda/ruby

Using an Amazon base image for Ruby

To complete the steps in this section, you must have the following:

To create a container image for Ruby
  1. Create a directory for the project, and then switch to that directory.

    mkdir example cd example
  2. Create a new file called Gemfile. This is where you list your application's required RubyGems packages. The Amazon SDK for Ruby is available from RubyGems. You should choose specific Amazon service gems to install. For example, to use the Ruby gem for Lambda, your Gemfile should look like this:

    source 'https://rubygems.org' gem 'aws-sdk-lambda'

    Alternatively, the aws-sdk gem contains every available Amazon service gem. This gem is very large. We recommend that you use it only if you depend on many Amazon services.

  3. Install the dependencies specified in the Gemfile using bundle install.

    bundle install
  4. Create a new file called lambda_function.rb. You can add the following sample function code to the file for testing, or use your own.

    Example Ruby function
    module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
  5. Create a new Dockerfile. The following is an example Dockerfile that uses an Amazon base image. This Dockerfiles uses the following configuration:

    • Set the FROM property to the URI of the base image.

    • Use the COPY command to copy the function code and runtime dependencies to {LAMBDA_TASK_ROOT}.

    • Set the CMD argument to the Lambda function handler.

    Example Dockerfile
    FROM public.ecr.aws/lambda/ruby:3.2 # Copy function code COPY lambda_function.rb ${LAMBDA_TASK_ROOT}/ # Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:2.4.14 && \ bundle install --path vendor/bundle # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process" ]
  6. Build the Docker image with the docker build command. The following example names the image docker-image and gives it the test tag.

    docker build --platform linux/amd64 -t docker-image:test .
    Note

    The command specifies the --platform linux/amd64 option 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/arm64 option instead.

  1. Start the Docker image with the docker run command. In this example, docker-image is the image name and test is the tag.

    docker run -p 9000:8080 docker-image:test

    This command runs the image as a container and creates a local endpoint at localhost:9000/2015-03-31/functions/function/invocations.

  2. From a new terminal window, post an event to the following endpoint using a curl command:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

    This command invokes the function with an empty event and returns a response. If you're using your own function code rather than the sample function code, you might want to invoke the function with a JSON payload. Example:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
  3. Get the container ID.

    docker ps
  4. Use the docker kill command to stop the container. In this command, replace 3766c4ab331c with the container ID from the previous step.

    docker kill 3766c4ab331c
To upload the image to Amazon ECR and create the Lambda function
  1. Run the get-login-password command to authenticate the Docker CLI to your Amazon ECR registry.

    • Set the --region value to the Amazon Web Services Region where you want to create the Amazon ECR repository.

    • Replace 111122223333 with your Amazon Web Services account ID.

    aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn
  2. Create a repository in Amazon ECR using the create-repository command.

    aws ecr create-repository --repository-name hello-world --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

    If successful, you see a response like this:

    { "repository": { "repositoryArn": "arn:aws: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" } } }
  3. Copy the repositoryUri from the output in the previous step.

  4. Run the docker tag command to tag your local image into your Amazon ECR repository as the latest version. In this command:

    • Replace docker-image:test with the name and tag of your Docker image.

    • Replace <ECRrepositoryUri> with the repositoryUri that you copied. Make sure to include :latest at the end of the URI.

    docker tag docker-image:test <ECRrepositoryUri>:latest

    Example:

    docker tag docker-image:test 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
  5. Run the docker push command to deploy your local image to the Amazon ECR repository. Make sure to include :latest at the end of the repository URI.

    docker push 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
  6. 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.

  7. Create the Lambda function. For ImageUri, specify the repository URI from earlier. Make sure to include :latest at the end of the URI.

    aws lambda create-function \ --function-name hello-world \ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest \ --role arn:aws:iam::111122223333:role/lambda-ex
  8. Invoke the function.

    aws lambda invoke --function-name hello-world response.json

    You should see a response like this:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. To see the output of the function, check the response.json file.

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 command to deploy the image to the Lambda function.

Using an alternative base image with the runtime interface client

If you use a base image for custom runtimes or an alternative base image, you must include the runtime interface client in your image. The runtime interface client extends the Lambda runtime API, which manages the interaction between Lambda and your function code.

Install the Lambda runtime interface client for Ruby using the RubyGems.org package manager:

gem install aws_lambda_ric

You can also download the Ruby runtime interface client from GitHub. The runtime interface client supports Ruby versions 2.5.x to 2.7.x.

The following example demonstrates how to build a container image for Ruby using a non-Amazon base image. The example Dockerfile uses an official Ruby base image. The Dockerfile includes the runtime interface client.

To complete the steps in this section, you must have the following:

To create a container image for Ruby using an alternative base image
  1. Create a directory for the project, and then switch to that directory.

    mkdir example cd example
  2. Create a new file called Gemfile. This is where you list your application's required RubyGems packages. The Amazon SDK for Ruby is available from RubyGems. You should choose specific Amazon service gems to install. For example, to use the Ruby gem for Lambda, your Gemfile should look like this:

    source 'https://rubygems.org' gem 'aws-sdk-lambda'

    Alternatively, the aws-sdk gem contains every available Amazon service gem. This gem is very large. We recommend that you use it only if you depend on many Amazon services.

  3. Install the dependencies specified in the Gemfile using bundle install.

    bundle install
  4. Create a new file called lambda_function.rb. You can add the following sample function code to the file for testing, or use your own.

    Example Ruby function
    module LambdaFunction class Handler def self.process(event:,context:) "Hello from Lambda!" end end end
  5. Create a new Dockerfile. The following Dockerfile uses a Ruby base image instead of an Amazon base image. The Dockerfile includes the runtime interface client for Ruby, which makes the image compatible with Lambda. Alternatively, you can add the runtime interface client to your application's Gemfile.

    • Set the FROM property to the Ruby base image.

    • Use the COPY command to copy the function code and runtime dependencies to {LAMBDA_TASK_ROOT}.

    • Set the ENTRYPOINT to 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 CMD argument to the Lambda function handler.

    Example Dockerfile
    FROM ruby:2.7 # Install the runtime interface client for Ruby RUN gem install aws_lambda_ric # Add the runtime interface client to the PATH ENV PATH="/usr/local/bundle/bin:${PATH}" # Create a directory for the Lambda function ENV LAMBDA_TASK_ROOT=/var/task RUN mkdir -p ${LAMBDA_TASK_ROOT} WORKDIR ${LAMBDA_TASK_ROOT} # Copy function code COPY lambda_function.rb ${LAMBDA_TASK_ROOT}/ # Copy Gemfile and Gemfile.lock COPY Gemfile Gemfile.lock ${LAMBDA_TASK_ROOT}/ # Install Bundler and the specified gems RUN gem install bundler:1.17.3 && \ bundle install --path vendor/bundle # Set runtime interface client as default command for the container runtime ENTRYPOINT [ "aws_lambda_ric" ] # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "lambda_function.LambdaFunction::Handler.process" ]
  6. Build the Docker image with the docker build command. The following example names the image docker-image and gives it the test tag.

    docker build --platform linux/amd64 -t docker-image:test .
    Note

    The command specifies the --platform linux/amd64 option 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/arm64 option instead.

Use the runtime interface emulator to locally test the image. You can build the emulator into your image or install it on your local machine.

To install and run the runtime interface emulator on your local machine
  1. 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.

    mkdir -p ~/.aws-lambda-rie && \ curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \ chmod +x ~/.aws-lambda-rie/aws-lambda-rie

    To install the arm64 emulator, replace the GitHub repository URL in the previous command with the following:

    https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
  2. Start the Docker image with the docker run command. Note the following:

    • docker-image is the image name and test is the tag.

    • aws_lambda_ric lambda_function.LambdaFunction::Handler.process is the ENTRYPOINT followed by the CMD from your Dockerfile.

    docker run -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \ --entrypoint /aws-lambda/aws-lambda-rie \ docker-image:test \ aws_lambda_ric lambda_function.LambdaFunction::Handler.process

    This command runs the image as a container and creates a local endpoint at localhost:9000/2015-03-31/functions/function/invocations.

  3. Post an event to the following endpoint using a curl command:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

    This command invokes the function with an empty event and returns a response. Some functions might require a JSON payload. Example:

    curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
  4. Get the container ID.

    docker ps
  5. Use the docker kill command to stop the container. In this command, replace 3766c4ab331c with the container ID from the previous step.

    docker kill 3766c4ab331c
To upload the image to Amazon ECR and create the Lambda function
  1. Run the get-login-password command to authenticate the Docker CLI to your Amazon ECR registry.

    • Set the --region value to the Amazon Web Services Region where you want to create the Amazon ECR repository.

    • Replace 111122223333 with your Amazon Web Services account ID.

    aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn
  2. Create a repository in Amazon ECR using the create-repository command.

    aws ecr create-repository --repository-name hello-world --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE

    If successful, you see a response like this:

    { "repository": { "repositoryArn": "arn:aws: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" } } }
  3. Copy the repositoryUri from the output in the previous step.

  4. Run the docker tag command to tag your local image into your Amazon ECR repository as the latest version. In this command:

    • Replace docker-image:test with the name and tag of your Docker image.

    • Replace <ECRrepositoryUri> with the repositoryUri that you copied. Make sure to include :latest at the end of the URI.

    docker tag docker-image:test <ECRrepositoryUri>:latest

    Example:

    docker tag docker-image:test 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
  5. Run the docker push command to deploy your local image to the Amazon ECR repository. Make sure to include :latest at the end of the repository URI.

    docker push 111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest
  6. 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.

  7. Create the Lambda function. For ImageUri, specify the repository URI from earlier. Make sure to include :latest at the end of the URI.

    aws lambda create-function \ --function-name hello-world \ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.cn-north-1.amazonaws.com.cn/hello-world:latest \ --role arn:aws:iam::111122223333:role/lambda-ex
  8. Invoke the function.

    aws lambda invoke --function-name hello-world response.json

    You should see a response like this:

    { "ExecutedVersion": "$LATEST", "StatusCode": 200 }
  9. To see the output of the function, check the response.json file.

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 command to deploy the image to the Lambda function.