Repository navigation
Pin @swc/core so the app boots read-only, and boot the image in PR CI - #144
Merged
Merged
Conversation
next.config.ts loads next-intl's plugin, which requires @swc/core at load time. From 1.16.12, @swc/core's native addon unpacks itself into a cache directory on first load (~/.cache, then /tmp) and refuses to load unless that directory is writable and executable. A container with a read-only root filesystem and a noexec /tmp has neither, so `next start` throws ERR_SWC_NATIVE_CACHE while loading the config; the web process exits and the start script takes the api and worker down with it. 1.16.2 is the last release that loads its addon in place, and the one the lockfile resolved before. It is inside next-intl 4.14.9's declared range (~1.16.0). Pointing SWC_NATIVE_BINDING_CACHE at an executable tmpfs would also work, but every deployment's compose file would need that mount; the pin fixes the image itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The image job only built the image, so nothing ran it the way the compose files do: read-only root filesystem, non-root user, and Docker's default tmpfs mounts, which are noexec. A dependency that needs a writable or executable path outside those mounts passed CI and failed only once deployed, as @swc/core does from 1.16.12. The job now loads the image and starts it with the compose services' runtime flags, the same tmpfs paths, a throwaway Postgres and the four variables a boot needs (APP_BASE_URL included: auth refuses to start without it in production mode). It passes once the dashboard's /login and the API's /health both answer, and fails with the container's logs if the container stops or two minutes pass first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v0.15.0's app container restart-loops at boot, so this is the hotfix for v0.15.1.
What fails
next startloadsnext.config.ts, which loads next-intl's plugin, and next-intl loads@swc/core. #139 moved@swc/corefrom 1.16.2 to 1.16.18 through next-intl's~1.16.0range. From 1.16.12,@swc/coreunpacks its native addon into a user cache directory on first load and refuses to load without one it can write and execute from:The compose files run the app with a read-only root filesystem, as a non-root user, with Docker's default (noexec) tmpfs at
/tmp. So web exits, and the start script stops the api and the worker with it.The fix
Pin
@swc/coreto 1.16.2 with an override inpnpm-workspace.yaml, the version v0.14.0 shipped. The lockfile changes only the swc packages, and their integrity hashes match v0.14.0's. next-intl 4.14.9 declares~1.16.0, so 1.16.2 is in range.Boot the image in pull request CI the way the compose files run it. The
imagejob now loads the app image and runs it with:--cap-drop ALL/no-new-privileges;The step passes once
/loginand the API's/healthboth answer; otherwise it prints the container's logs. A dependency that needs to write or execute outside those mounts now fails here, before a release.Verified
/login200,/healthok, and api, worker and web all stayed up.pnpm lint,pnpm typecheckand the apps/web suite (1277 tests) pass.🤖 Generated with Claude Code