ECR Container Lambdas
Deploy Lambda functions as Docker container images instead of ZIP bundles — useful for binaries, large dependencies, or custom runtimes.
Define a Container Lambda
Use defineLambda with packageType: 'container' in a standalone Lambda:
typescript
// src/lambdas/standalone/DownloadMedia/index.ts
import { defineLambda } from '@mantleframework/core'
defineLambda({
packageType: 'container',
dockerfile: 'Dockerfile.download', // relative to project root
architecture: 'x86_64', // or 'arm64' (default)
memorySize: 2048,
timeout: 900,
dockerBuildArgs: {
YTDLP_VERSION: '2026.03.25',
DENO_VERSION: '2.2.0',
},
dockerTarget: 'production', // multi-stage target (optional)
})
export const handler = async (event: unknown) => {
// handler logic
return { statusCode: 200 }
}Write a Dockerfile
The build step runs esbuild first, then calls docker build. Your Dockerfile receives the compiled index.mjs in the build output directory:
dockerfile
FROM public.ecr.aws/lambda/nodejs:22
# Install runtime dependencies
RUN dnf install -y yt-dlp
# Copy compiled handler
COPY build/lambdas/DownloadMedia/index.mjs ${LAMBDA_TASK_ROOT}/
CMD ["index.handler"]Build
bash
mantle buildmantle build detects container Lambdas and requires Docker to be running. It:
- Runs esbuild (same as ZIP — produces
index.mjs) - Computes a content hash of the Dockerfile + build output
- Runs
docker build --platform linux/amd64|arm64 -t <name>:<hash> - Writes a
.image-tagfile tobuild/lambdas/<Name>/
Deploy
bash
mantle deploy --stage stagingmantle deploy automatically authenticates with ECR, tags the image, and pushes before running OpenTofu:
aws ecr get-login-password | docker login ...
docker tag downloadmedia:<hash> <account>.dkr.ecr.<region>.amazonaws.com/<prefix>/download-media:<hash>
docker push ...
tofu apply -var image_uri_download_media=<full-uri> ...Generated Infrastructure
mantle generate infra produces a .tf file per container Lambda with:
aws_ecr_repository— IMMUTABLE tags, scan-on-push enabledaws_ecr_lifecycle_policy— retains last N images (default: 5)- Lambda module block with
package_type = "Image"andimage_urifrom a Terraform variable
hcl
resource "aws_ecr_repository" "download_media" {
name = "${module.core.name_prefix}/download-media"
image_tag_mutability = "IMMUTABLE"
force_delete = true
image_scanning_configuration {
scan_on_push = true
}
tags = module.core.common_tags
}Optional: Registry Configuration
typescript
// mantle.config.ts
export default defineConfig({
name: 'my-api',
containerRegistry: {
repositoryPrefix: 'my-prefix', // default: name_prefix from core module
tagStrategy: 'content-hash', // 'content-hash' | 'git-sha' | 'timestamp'
imageRetentionCount: 10, // default: 5
},
})Constraints
- Container Lambdas cannot use
layers— layers are ZIP-only (warning emitted at build time) - Container Lambdas cannot use
edge: true— Lambda@Edge does not support container images (build fails) dockerfilepath is relative to the project root, not the Lambda directory