How to Build and Deploy Python Libraries for AWS Lambda Layers

3 min read

Lambda Layers let you package Python libraries once and share them across multiple Lambda functions. Instead of bundling dependencies into every deployment package, you build a layer with your libraries and attach it to any function that needs them. This guide shows you how to build Python Lambda Layers using Docker (to match the Lambda runtime) and deploy them with the AWS CLI.

The examples here are run on WSL2 Ubuntu in Windows, but they work the same on any Linux or macOS system.

Prerequisites

  • AWS CLI v2 installed and configured with credentials
  • Docker installed and running
  • IAM permissions for lambda:PublishLayerVersion

Why Use Docker to Build Layers?

Some Python packages (like pandas, numpy, or psycopg2) include compiled C extensions. If you pip install them on your Mac or Windows machine, the binaries won’t work inside Lambda’s Amazon Linux environment. Building inside a Docker container that matches the Lambda runtime ensures compatibility.

Step 1: Set Up the Project

Create a directory for your layer build:

mkdir -p lambda-layer
cd lambda-layer

Create a requirements.txt with the libraries your functions need:

requests==2.32.3
boto3==1.35.0
pydantic==2.10.0

Pin your versions. Lambda Layers should be reproducible — you don’t want a surprise upgrade breaking your functions.

Step 2: Install Dependencies with Docker

Lambda expects layer contents in a python/ directory. Use Docker to install the packages into the correct structure:

docker run --rm -v "$(pwd)":/var/task \
  public.ecr.aws/lambda/python:3.12 \
  pip install -r /var/task/requirements.txt \
  -t /var/task/python \
  --no-cache-dir
  • public.ecr.aws/lambda/python:3.12 — official Lambda Python 3.12 image, matches the runtime exactly
  • -v "$(pwd)":/var/task — mounts your current directory into the container
  • -t /var/task/python — installs packages into the python/ directory (required by Lambda)
  • --no-cache-dir — skips pip’s cache to keep the layer size smaller

After this runs, you’ll have a python/ directory with all the installed packages.

Change the image tag to match your target runtime: python:3.11, python:3.12, or python:3.13.

Step 3: Create the ZIP Archive

zip -r layer.zip python/

The ZIP must contain the python/ directory at the root. Lambda extracts the layer and adds python/ to the Python path automatically.

Check the size — Lambda Layers have a 250 MB unzipped limit (50 MB zipped for direct upload). If your zip exceeds 50 MB, upload it to S3 first and reference the S3 URI in the publish command.

Step 4: Publish the Layer

aws lambda publish-layer-version \
  --layer-name my-python-libs \
  --zip-file fileb://layer.zip \
  --compatible-runtimes python3.12 \
  --compatible-architectures x86_64 \
  --region ap-southeast-1
  • --layer-name — a descriptive name for the layer
  • --compatible-runtimes — which Python versions this layer works with (you can list multiple)
  • --compatible-architectures — use x86_64 or arm64 depending on your Lambda function’s architecture

The command returns the layer ARN and version number. Save the ARN — you’ll need it to attach the layer to your functions.

For layers larger than 50 MB (zipped)

Upload to S3 first, then reference it:

aws s3 cp layer.zip s3://your-deploy-bucket/layers/layer.zip

aws lambda publish-layer-version \
  --layer-name my-python-libs \
  --content S3Bucket=your-deploy-bucket,S3Key=layers/layer.zip \
  --compatible-runtimes python3.12 \
  --compatible-architectures x86_64 \
  --region ap-southeast-1

Step 5: Attach the Layer to a Lambda Function

aws lambda update-function-configuration \
  --function-name my-function \
  --layers arn:aws:lambda:ap-southeast-1:123456789012:layer:my-python-libs:1 \
  --region ap-southeast-1

Replace the ARN with the one returned in Step 4. The :1 at the end is the version number — each publish creates a new version.

You can also attach layers in the Lambda console under Function > Layers > Add a layer.

Verify the Layer Works

Create a quick test function that imports one of the layer’s packages:

import requests

def lambda_handler(event, context):
    return {"statusCode": 200, "body": requests.__version__}

If it returns the version number, the layer is working. If you get a ModuleNotFoundError, check that:

  • The ZIP contains python/ at the root (not nested inside another directory)
  • The runtime version matches between the layer and the function
  • The architecture matches (x86_64 vs arm64)

For more on writing Lambda functions, see Understanding Lambda’s Event and Context Parameters.

Conclusion

Building Lambda Layers with Docker ensures your Python packages are compiled for the right environment. The workflow is: pip install into python/ using the official Lambda image, zip it, and publish with the AWS CLI. Once published, any function in your account can use the layer.

For organizing your Lambda code alongside layers, check out How to Structure Your Python Projects for AWS Lambda, APIs, and CLI Tools.