Summary
Deploying a container image based on distroless (gcr.io/distroless/static-debian12:nonroot and gcr.io/distroless/cc-debian12:nonroot) to AWS Lambda via the rowdy GitHub Action fails at runtime with:
Runtime.InvalidEntrypoint
Error: fork/exec /usr/local/bin/rowdy: permission denied
Switching the same app to a debian:bookworm-slim base fixed it immediately. Something about the distroless base prevents rowdy's injected entrypoint from executing.
Environment
- rowdy:
@scaffoldly/rowdy@0.1.0-beta.20260618101044.2b9b3ab (scaffoldly/rowdy@github)
- Cloud/compute: AWS Lambda,
Architectures: ["x86_64"], container (Image) package type
- App: tiny Go HTTP server (static
CGO_ENABLED=0 binary), single ENTRYPOINT ["/app-binary"]
- Registry flow: GitHub Actions builds & pushes to GHCR → rowdy pulls from GHCR, repackages, pushes to ECR, configures Lambda
What rowdy configured on the function (from deploy logs)
ImageConfigResponse.ImageConfig:
EntryPoint: ["rowdy", "--"]
Command: ["/etcd.nanokube.run"]
WorkingDirectory: /home/nonroot
The rowdy binary lands at /usr/local/bin/rowdy, mode -rwxr-xr-x, owner root, valid x86-64 ELF. Parent dirs (/usr, /usr/local, /usr/local/bin) are all drwxr-xr-x. By file-mode permissions alone it should be executable — yet Lambda reports permission denied.
Reproduction
Final stage of the Dockerfile (fails):
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /out/etcd.nanokube.run /etcd.nanokube.run
ENTRYPOINT ["/etcd.nanokube.run"]
Also tried gcr.io/distroless/cc-debian12:nonroot (adds glibc + libstdc++) — same failure.
Works:
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /out/etcd.nanokube.run /etcd.nanokube.run
ENTRYPOINT ["/etcd.nanokube.run"]
Notes / possible causes
- The rowdy binary appears to be a bundled Node.js executable (~119 MB, contains
Node.js strings). On a distroless base it cannot be exec'd by the Lambda runtime; on debian it can.
WorkingDirectory: /home/nonroot is set, which exists in distroless :nonroot images but the entrypoint still fails — so it's not (only) a missing-cwd issue.
- Whatever rowdy's injected entrypoint needs at runtime (loader, shell, or a writable/searchable path) is present in debian but absent in distroless.
Ask
Please document the supported/required base image(s) for rowdy-deployed Lambda containers, and/or make the injected entrypoint work on distroless bases (or fail early with a clear error during deploy instead of Runtime.InvalidEntrypoint at cold start).
Summary
Deploying a container image based on distroless (
gcr.io/distroless/static-debian12:nonrootandgcr.io/distroless/cc-debian12:nonroot) to AWS Lambda via the rowdy GitHub Action fails at runtime with:Switching the same app to a
debian:bookworm-slimbase fixed it immediately. Something about the distroless base prevents rowdy's injected entrypoint from executing.Environment
@scaffoldly/rowdy@0.1.0-beta.20260618101044.2b9b3ab(scaffoldly/rowdy@github)Architectures: ["x86_64"], container (Image) package typeCGO_ENABLED=0binary), singleENTRYPOINT ["/app-binary"]What rowdy configured on the function (from deploy logs)
The rowdy binary lands at
/usr/local/bin/rowdy, mode-rwxr-xr-x, owner root, valid x86-64 ELF. Parent dirs (/usr,/usr/local,/usr/local/bin) are alldrwxr-xr-x. By file-mode permissions alone it should be executable — yet Lambda reportspermission denied.Reproduction
Final stage of the Dockerfile (fails):
Also tried
gcr.io/distroless/cc-debian12:nonroot(adds glibc + libstdc++) — same failure.Works:
Notes / possible causes
Node.jsstrings). On a distroless base it cannot be exec'd by the Lambda runtime; on debian it can.WorkingDirectory: /home/nonrootis set, which exists in distroless:nonrootimages but the entrypoint still fails — so it's not (only) a missing-cwd issue.Ask
Please document the supported/required base image(s) for rowdy-deployed Lambda containers, and/or make the injected entrypoint work on distroless bases (or fail early with a clear error during deploy instead of
Runtime.InvalidEntrypointat cold start).