Building on Amazon Linux 2023
The glibc constraint
Two facts collide:
- Lambda's
provided.al2023execution environment is based on the AL2023 minimal container image: < 40 MB, no language runtime, **glibc 2.34**. - Jolt's prebuilt Linux x86_64 binary requires glibc ≥ 2.35 (Ubuntu 22.04+, jolt README).
glibc is backward-compatible only: a binary built against an older glibc runs on a newer one, never the reverse. So neither the Homebrew joltc (macOS) nor the release Linux joltc can produce a deployable binary. The bootstrap must be built by a from-source jolt running on AL2023 itself, so it links 2.34.
The recipe (Dockerfile)
Mirrors jolt's own CI (.github/workflows/tests.yml) transplanted to dnf:
- Chez Scheme from source (
CHEZ_VERSIONbuild arg, default10.4.1),./configure --installprefix=/opt/chez --threads --disable-x11. From source because distro chez packages ship no kernel dev files (libkernel.a,scheme.h), whichjoltc buildneeds to link the self-contained executable. Achezwrapper execing/opt/chez/bin/schemegoes next toschemeso jolt's build derives the kernel-file location from it. - Jolt from a fresh clone (
JOLT_VERSIONbuild arg, default0.8.7,--recurse-submodules). Its bootstrap seed is checked in: clone and run, no build step. joltc build -m net.b12n.lambda-mvp.main -o bootstrap: fetches thedeps.edngit deps, compiles app + runtime + stdlib, links one executable.lddaudit →lib/: every non-glibc.sothe binary links is copied intolib/, plus the http-client's dlopened trio (libz.so.1,libssl.so.3,libcrypto.so.3) whichlddcannot see. Lambda'sLD_LIBRARY_PATHincludes/var/task/lib, so the zip is self-sufficient. glibc itself is excluded: that must come from the execution environment.zip -r lambda.zip bootstrap liband aFROM scratchexport stage sodocker build --target export --output dist .dropsdist/bootstrap+dist/lambda.zipon the host.
Chez statically links its vendored zlib and lz4, which keeps the lib/ bundle short.
JOLT_VERSION/CHEZ_VERSION are build args, not constants
Both are overridable: JOLT_VERSION=0.7.14 jolt image rebuilds against an older jolt release without editing the Dockerfile. This is what makes docs/guide/cold-warm-boot.md's jolt-version comparison reproducible rather than a one-time historical claim.
AL2023 packaging gotchas (each cost one build round in the source project)
whichis not installed.bin/joltclocates chez viawhich→ install thewhichpackage.xxdis not installed. jolt's self-contained link embeds the boot image viaxxd -i→xxdships in thevim-commonpackage.- These live in a separate
RUN dnf installlayer placed after the Chez build so fixing them doesn't invalidate the ~4-minute Chez layer.
arm64 and x86_64
By default the build targets linux/arm64 (native on Apple Silicon Docker, no qemu) and deploys to Lambda --architectures arm64 (Graviton, cheaper per GB-second). Chez v10 supports aarch64le Linux; jolt's release binaries don't cover aarch64 Linux, but the from-source build works.
LAMBDA_ARCH=x86_64 jolt image (amd64 also accepted) builds the identical Dockerfile under --platform linux/amd64 instead. jolt deploy reads the architecture from dist/bootstrap's ELF header, so it always matches the last build, including when it switches an existing function's architecture.
Building for the architecture your machine isn't needs qemu. Docker Desktop ships it; on a plain Linux Docker Engine, a missing emulator fails the first RUN with exec /bin/sh: exec format error. Either build natively (on an x86_64 Linux host, LAMBDA_ARCH=x86_64) or register the emulator, e.g. docker run --privileged --rm tonistiigi/binfmt --install arm64. Expect an emulated Chez build to be several times slower.