Skip to main content

Run in production

A production container has a credential, runs read-only as a non-root user without capabilities, has memory, CPU and process limits, and a healthcheck. The binary and the function code are mounted read-only.

1. Create the credentials​

Only the SHA-256 of the bearer token enters the container. Give the token itself to the callers.

TOKEN=$(openssl rand -hex 32) # for the callers, never for the container
TOKEN_SHA256=$(printf %s "$TOKEN" | openssl dgst -sha256 -r | cut -d' ' -f1)
KEY_ID=$(LC_ALL=C tr -dc A-Z0-9 </dev/urandom | head -c 20) # optional SigV4 pair
KEY_SECRET=$(openssl rand -base64 30)
printf 'LOCH_RUNTIME_TOKEN_SHA256=%s\nLOCH_RUNTIME_ACCESS_KEY=%s:%s\n' "$TOKEN_SHA256" "$KEY_ID" "$KEY_SECRET" > fn.env
chmod 600 fn.env

Keep both values secret. The SigV4 pair is only needed for the AWS CLI and SDKs. Details: Authentication.

2. Start the container​

fn/ holds the function code and $ARCH matches the host, as in the quick start.

docker network create fn-net
docker run -d --name fn --network fn-net \
--read-only --user 10001:10001 --cap-drop ALL --security-opt no-new-privileges:true \
--tmpfs /tmp:size=64m --memory 256m --memory-swap 256m --cpus 0.5 --pids-limit 128 \
-p 127.0.0.1:8080:8080 \
-v "$PWD/loch-lambda-runtime-linux-$ARCH:/loch/lambda-runtime:ro" \
-v "$PWD/fn:/var/task:ro" \
--env-file fn.env -e AWS_LAMBDA_FUNCTION_TIMEOUT=30 \
--entrypoint /loch/lambda-runtime \
public.ecr.aws/lambda/nodejs:22 index.handler
until docker exec fn /loch/lambda-runtime health >/dev/null; do sleep 0.2; done
OptionWhy
--read-only, --tmpfs /tmpThe function writes to /tmp only, as on AWS Lambda™
--user 10001:10001Any non-root uid. As root, credential files are harder to protect
--cap-drop ALL, no-new-privilegesThe runtime needs no capability
--memory = --memory-swapNo swap. The runtime reads the limit and sets AWS_LAMBDA_FUNCTION_MEMORY_SIZE (256)
--cpus, --pids-limitBound what the function can use
-p 127.0.0.1:8080:8080Publish on the loopback only, or not at all: callers on fn-net use http://fn:8080

Invoke it: see Invoke a function.

3. Add a healthcheck​

docker run --health-cmd only has the shell form, which you must not use. Use compose and the exec form:

services:
fn:
image: public.ecr.aws/lambda/nodejs:22
entrypoint: ["/loch/lambda-runtime"]
command: ["index.handler"]
user: "10001:10001"
read_only: true
cap_drop: [ALL]
security_opt: ["no-new-privileges:true"]
tmpfs: ["/tmp:size=64m"]
mem_limit: 256m
memswap_limit: 256m
cpus: 0.5
pids_limit: 128
env_file: fn.env
environment:
AWS_LAMBDA_FUNCTION_TIMEOUT: "30"
volumes:
- ./loch-lambda-runtime-linux-amd64:/loch/lambda-runtime:ro # or -linux-arm64
- ./fn:/var/task:ro
healthcheck:
test: ["CMD", "/loch/lambda-runtime", "health"]
interval: 10s
timeout: 5s

This compose file applies the options above; it is not tested in CI. health exits 0 when the function is ready, 1 otherwise (initializing, init error, stopping).

Limits​

SettingDefaultEffect
AWS_LAMBDA_FUNCTION_TIMEOUT300 (s)Longer invocations are stopped and get Sandbox.Timedout
LOCH_RUNTIME_QUEUE_SIZE16Waiting invocations; beyond, 429
LOCH_RUNTIME_QUEUE_BYTESmin(32MiB, memory/8)Total size of the waiting invocations; beyond, 429
LOCH_RUNTIME_QUEUE_TIMEOUT30sLongest wait in the queue; beyond, 429
LOCH_RUNTIME_MAX_PAYLOAD6MiBLarger requests get 413
LOCH_RUNTIME_SHUTDOWN_GRACE8sTime left to the running invocation on docker stop

Full list: Configuration reference.

Good to know​

  • Never use --network host: the loopback needs no credential, so every process of the host could invoke the function.
  • Keep LOCH_RUNTIME_SHUTDOWN_GRACE shorter than the container stop timeout (stop_grace_period, 10 s by default in Docker). On SIGTERM, queued invocations get 503.
  • A tmpfs counts against the container memory limit.
  • The Invoke API is plain HTTP: keep it on private networks.
  • Never bill or alert on the function's logs: its code can forge START/END/REPORT lines. Use metrics.

"AWS" and "AWS Lambda" are trademarks of Amazon.com, Inc. or its affiliates. This project is not affiliated with or endorsed by Amazon. It implements the publicly documented AWS Lambda Runtime and Invoke APIs and contains no code from the AWS Lambda Runtime Interface Emulator.