Skip to content

Hotfix 0.52.2 — fix Sharp/glibc image-optimizer 500s on the Chainguard runtime#425

Merged
elfensky merged 1 commit into
mainfrom
hotfix/0.52.2
Jun 11, 2026
Merged

Hotfix 0.52.2 — fix Sharp/glibc image-optimizer 500s on the Chainguard runtime#425
elfensky merged 1 commit into
mainfrom
hotfix/0.52.2

Conversation

@elfensky

Copy link
Copy Markdown
Owner

Problem (production incident, follows v0.52.1)

After v0.52.1 deployed, every optimized image (/_next/image — avatars, icons, background) returned 500 at the origin (502 through nginx/Cloudflare). Server logs:

⨯ Error: Could not load the "sharp" module using the linux-x64 runtime

Root cause: a latent bug unmasked by the 0.52.1 .next/cache permission fix. Previously the optimizer died at mkdir('.next/cache') (EACCES) before ever loading Sharp. Now that the cache is writable, it reaches Sharp — and fails, because Dockerfile.app built on node:24-alpine (musl) and stripped Sharp's glibc binaries, while the runtime image cgr.dev/chainguard/node is glibc (Wolfi). So only @img/sharp-linuxmusl-x64 shipped into a glibc runtime.

Diagnosis on the live container:

  • require('sharp')Could not load the "sharp" module using the linux-x64 runtime
  • @img had only sharp-linuxmusl-x64; process.report … glibcVersionRuntime: 2.43 (glibc runtime)

(Prisma was unaffected because it uses the @prisma/adapter-pg JS driver — no native engine — which is why the DB worked but images didn't.)

Fix

Build on a glibc base (node:24 Debian) instead of node:24-alpine, and drop the musl-only Sharp strip. Sharp's glibc binary (@img/sharp-linux-x64) is then installed, traced into the standalone output, and loads on the glibc Chainguard runtime.

Verification (real linux/amd64 image, matching production)

Check Result
@img contents sharp-linux-x64 (glibc) present
require('sharp') OK — sharp 0.34.5 / vips 8.17.3
encode a WebP OK — sharp({create…}).webp().toBuffer() succeeds

(An initial arm64 local build passed too but tested the wrong arch — re-verified on amd64 to match prod.)

Deploy after tagging (v0.52.2)

Bump the server docker-compose.yml images to v0.52.2 (app + migrate), docker compose pull && up -d. Also finally swap the curl healthcheck for the node-based probe — Chainguard has no curl, so the container shows unhealthy (harmless to serving, but wrong).

🤖 Generated with Claude Code

…time

The 0.52.1 .next/cache fix let the Next.js image optimizer finally run, which
unmasked a latent Sharp failure: Dockerfile.app built on node:24-alpine (musl)
and stripped Sharp's glibc binaries, but the runtime image
cgr.dev/chainguard/node is glibc (Wolfi). Only @img/sharp-linuxmusl-x64 shipped
into a glibc runtime → "Could not load the sharp module using the linux-x64
runtime" → /_next/image 500s on every avatar/icon (502 at the edge).

Build on node:24 (Debian, glibc) and drop the musl-only strip so the glibc
Sharp binary (@img/sharp-linux-x64) is installed, traced into standalone, and
loads at runtime.

Verified on a real linux/amd64 build: @img includes sharp-linux-x64,
require('sharp') succeeds, and sharp encodes a WebP. Prisma unaffected (uses
the @prisma/adapter-pg JS driver, not a native engine).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@elfensky elfensky merged commit 6afe734 into main Jun 11, 2026
5 checks passed
@elfensky elfensky deleted the hotfix/0.52.2 branch June 11, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant