DEV Community

Cover image for how to deploy a docker container on aws lambda
anthony-campolo
anthony-campolo

Posted on

how to deploy a docker container on aws lambda

AWS Lambda is easy to use and manage because it has an execution environment with a specific runtime on a known environment. The problems come in when you have a use case outside these predetermined environments.

To address these issues AWS introduced Lambda layers, but Lambda layers still had limitations. In December 2020, AWS Lambda released some basic Docker container support. The Serverless framework has expanded on this with the following example designed to make it easier to use this new feature.

Create template with serverless create

We will use this starter template to generate a boilerplate already configured and setup in our serverless.yml file. All the code for this project can be found on my GitHub.

serverless create --template aws-nodejs-docker --path ajcwebdev-docker-lambda
Enter fullscreen mode Exit fullscreen mode

serverless.yml

The Serverless Framework lets you define a Dockerfile and point at it in serverless.yml. The Framework makes sure the container is available in ECR and that it is setup and configured for Lambda.

service: ajcwebdev-docker-lambda
frameworkVersion: '2'
Enter fullscreen mode Exit fullscreen mode

Under provider is an ecr section for defining images that will be built locally and uploaded to ECR. The entire packaging process occurs in the context of the container. AWS uses your Docker configuration to build, optimize and prepare your container for use in Lambda.

provider:
  name: aws
  lambdaHashingVersion: 20201221
  ecr:
    images:
      appimage:
        path: ./
Enter fullscreen mode Exit fullscreen mode

The functions section tells the framework what the image reference name is (appimage) that we can use elsewhere in our configuration, and where the content of the Docker image resides with the path property. A Dockerfile of some type should reside in the specified folder containing the executable code for our function.

functions:
  hello:
    image:
      name: appimage
Enter fullscreen mode Exit fullscreen mode

We use the same value for image.name as we do for the image we defined, appimage. It can be named anything as long as the same value is referenced.

dockerfile

The easiest way to setup a Lambda ready Docker image is to use base images provided by AWS. The AWS ECR Gallery contains a list of all available images. We are using the Node v12 image.

FROM public.ecr.aws/lambda/nodejs:12
COPY app.js ./
CMD ["app.handler"]
Enter fullscreen mode Exit fullscreen mode

The CMD property defines a file called app.js with a function called handler.

app.js

In our service's directory, we have a file called app.js with the function inside.

'use strict'

module.exports.handler = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: `Cause I don't want a server, but I do still want a container`,
      },
      null,
      2
    ),
  }
}
Enter fullscreen mode Exit fullscreen mode

app.js returns a JSON object containing a message clarifying exactly why anyone would ever want this thing in the first place.

Deploy with serverless deploy

We are now able to generate our container, deploy it to ECR and execute functions. In order to build images locally and push them to ECR, you need to have Docker installed and running on your local machine.

cd ajcwebdev-docker-lambda
serverless deploy
Enter fullscreen mode Exit fullscreen mode

The serverless deploy command deploys your entire service via CloudFormation. After the deployment finishes you will be provided the information for your service.

Service Information

service: ajcwebdev-docker-lambda
stage: dev
region: us-east-1
stack: ajcwebdev-docker-lambda-dev
resources: 6
api keys:
  None
endpoints:
  None
functions:
  hello: ajcwebdev-docker-lambda-dev-hello
layers:
  None
Enter fullscreen mode Exit fullscreen mode

Invoke the hello function with serverless invoke

The serverless invoke command invokes deployed function and allows sending event data to the function, reading logs and displaying other important information about the function invocation.

serverless invoke --function hello
Enter fullscreen mode Exit fullscreen mode

If your function/container was deployed correctly then you will receive the following message:

{
  "statusCode": 200,
  "body": "{\n  \"message\": \"Cause I don't want a server, but I do still want a container\"\n}"
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)