Self-hosted next/image works with next start without a separate image service. Production failures commonly come from request rules, a native binary built for another target, omitted traced files, filesystem permissions, or memory pressure.
Classify the failure first
A 400 response often indicates an invalid source or disallowed remote pattern. A module-load error points toward missing or incompatible native packages. A build that works on macOS but fails in Linux suggests cross-platform lockfile or binary selection. Timeouts and rising memory require runtime observation rather than reinstalling packages blindly.
Match build and runtime targets
Install dependencies for the production OS, CPU, and libc. Do not copy host node_modules into a container. Ensure optional dependencies are not omitted and inspect standalone traces when a runtime asset is missing. Keep tracing includes narrow if a native package needs explicit inclusion.
Check Linux memory behavior
The sharp documentation notes that glibc allocation can cause fragmentation in long-running, multi-threaded workloads and discusses alternative allocators. Measure RSS, request concurrency, image sizes, cache behavior, and process restarts before changing allocator or sharp concurrency.
If availability is urgent, a custom loader or unoptimized mode can bypass runtime transformation, but treat that as an explicit delivery tradeoff rather than proof the underlying packaging issue is solved.