@@ -9,6 +9,14 @@ FROM oven/bun:1.4.4-slim AS base
99# `isolated-vm` pin in apps/sim/package.json — Node 24 (ABI 137) requires
1010# isolated-vm 6.x.
1111#
12+ # NODE_VERSION pins the exact NodeSource build: this layer is cached, so an
13+ # unpinned `nodejs` changed only when an unrelated edit forced a rebuild. The
14+ # `-1nodesource1` suffix selects the `nodejs` package, never `nsolid`, which
15+ # Provides `nodejs` at the same version numbers. build-base and deps inherit
16+ # this stage, so isolated-vm's node-gyp build targets the same Node (and ABI)
17+ # the runner executes it with.
18+ ARG NODE_VERSION=24.22.1
19+ #
1220# Only what the running container needs belongs here. ffmpeg backs the media
1321# subprocess adapter; python3 is the node-gyp interpreter and is kept because
1422# build-base inherits from this stage. The compiler toolchain lives in build-base
@@ -24,7 +32,8 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
2432 apt-get update && apt-get install -y --no-install-recommends \
2533 python3 curl ca-certificates bash ffmpeg \
2634 && curl -fsSL https://deb.nodesource.com/setup_24.x | bash - \
27- && apt-get install -y nodejs \
35+ && apt-get install -y --no-install-recommends "nodejs=${NODE_VERSION}-1nodesource1" \
36+ && [ "$(node --version)" = "v${NODE_VERSION}" ] \
2837 && sed -i -E 's#^mozilla/(emSign_ECC_Root_CA_-_G3|Comodo_AAA_Services_root)\. crt$#!&#' /etc/ca-certificates.conf \
2938 && update-ca-certificates \
3039 && ! grep -qF -e 'l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3' -e 'CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD' /etc/ssl/certs/ca-certificates.crt
@@ -234,9 +243,20 @@ COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/lib/execution/sandbox/bu
234243# anonymizer, docker/pii.Dockerfile), reached over the network via PII_URL —
235244# no Python/Presidio in this image.
236245
237- # Create .next/cache directory with correct ownership
246+ # Writable paths for a read-only root filesystem. Declaring them as volumes
247+ # keeps writes working when the root is mounted read-only: ECS copies the
248+ # image's contents and ownership into a bind volume mounted at a VOLUME path.
249+ # - /tmp (mode 1777): os.tmpdir() scratch for ffmpeg and audio processing,
250+ # knowledge base imports, the Pi agent, and libvips (sharp) spill files.
251+ # - apps/sim/.next/cache: the Next image optimizer's disk cache
252+ # (.next/cache/images) and the data cache for `fetch` calls with
253+ # `next.revalidate`.
254+ # Keep the VOLUME line after every step that writes to these paths: the
255+ # classic builder discards later build-time changes to a declared volume.
238256RUN mkdir -p apps/sim/.next/cache && \
239- chown -R nextjs:nodejs apps/sim/.next/cache
257+ chown -R nextjs:nodejs apps/sim/.next/cache && \
258+ chmod 1777 /tmp
259+ VOLUME ["/tmp" , "/app/apps/sim/.next/cache" ]
240260
241261# Switch to non-root user
242262USER nextjs
0 commit comments