sharp, linux-x64, Could not load | 맥은 되는데 배포만 이미지가 죽으면?
Could not load the sharp module using the linux-x64 runtime은 맥에서 받은 바이너리가 리눅스 배포에 없을 때 납니다. optional 의존을 켜고 os, cpu, libc를 지정해 다시 설치합니다. 번들러는 sharp를 밖으로 뺍니다. ABI dlopen, 엣지 런타임과는 다릅니다. sharp, libvips, 버셀, 한국 1인 개발. 2026년 10월 문서.
배포 로그만 이미지 라이브러리를 못 읽는다면, 리사이즈 코드가 틀린 게 아니라 맥에서 받은 실행 파일이 리눅스 배포 폴더에 없는 자리입니다. 선택 설치를 켜고, 로그의 운영체제와 프로세서, 표준 라이브러리로 다시 받으세요.
노트북에서는 변환이 초록인데 프리뷰나 함수의 첫 이미지 요청만 죽습니다. 설치 순간 패키지 매니저는 지금 기계의 미리 컴파일된 파일을 고릅니다. 맥 파일은 리눅스 프로세스에서 안 열립니다.
설치 문서는 리눅스 64비트에 최소 표준 라이브러리와 특정 명령 집합을 적습니다. 런타임도 최근 노드부터입니다. 모듈 호환 숫자가 어긋난 불러오기, 엣지가 네이티브를 거절하는 줄과는 문장이 다릅니다. 근거는 설치 문서입니다.
설치가 지금 기계의 파일을 고른다
맥에서 npm install을 하면 다윈용 바이너리만 따라옵니다.
sharp는 자바스크립트 껍데기와 @img/sharp-linux-x64 같은 optional 패키지로 나뉩니다. --omit=optional이거나 설치 로그에 optional 실패가 있으면 껍데기만 남습니다. 배포 프로세스가 linux-x64로 뜨면 그 파일이 없어 Could not load가 납니다. musl(알파인)이면 로그의 런타임이 linuxmusl-x64 쪽입니다. glibc용 파일을 그 이름 대신 넣지 마세요.
리눅스 x64 프리빌드는 glibc 2.28 이상, CPU는 SSE4.2가 있어야 합니다. 아주 오래된 배포판이나 그 명령이 없는 CPU에서는 파일을 받아도 로드가 실패합니다. 그때는 플랫폼 이름을 바꾸기보다 런타임 이미지를 문서의 최소선에 맞춥니다.
버셀의 이미지 최적화는 플랫폼이 준비한 sharp를 쓸 수 있습니다. 이 문장은 내 서버 프로세스가 sharp를 직접 부를 때입니다. 라우트, 스탠드얼론 출력, 람다 압축 파일이 그 경우입니다.
렌즈(자바스크립트)와 기판(네이티브 바이너리)이 세트가 아니면 이미지가 안 열립니다
배포 OS를 지정해 다시 받는다
맥에 받은 폴더를 리눅스에 그대로 복사하지 않습니다.
npm 10부터는 --os, --cpu, --libc로 다른 플랫폼 파일을 같이 받을 수 있습니다. 리눅스는 C 라이브러리를 반드시 적습니다. 데비안·우분투·버셀의 노드 이미지는 보통 glibc, 알파인 이미지는 musl입니다. 로그의 런타임 문자열과 같은 쪽만 고릅니다.
받은 뒤 node_modules/@img 아래에 로그와 같은 플랫폼 폴더가 있는지 봅니다. 자바스크립트만 있고 @img가 비어 있으면 optional이 빠진 설치입니다. CI에 npm ci --omit=optional이 있으면 그 플래그를 빼야 이 명령이 의미가 있습니다.
한 락 파일이 다른 기계를 지운다
맥에서 만든 package-lock을 리눅스 CI가 그대로 쓰면 리눅스 파일이 빠질 수 있습니다.
sharp 문서는 npm package-lock.json을 여러 플랫폼이 공유하면 npm 이슈 4828 때문에 설치가 깨진다고 적습니다. 락을 지우는 것이 첫 처방은 아닙니다. 배포와 같은 OS에서 설치하거나, 위 플래그로 필요한 플랫폼을 락에 남깁니다.
pnpm 8+와 yarn 3+는 supportedArchitectures로 현재 기계와 리눅스 x64, glibc를 한 설치에 넣습니다. 키 이름은 각 매니저 문서가 정본입니다. npm 플래그를 yarn에 그대로 붙이면 락 형식이 달라 조용히 무시될 수 있습니다.
설치 환경
받는 파일
리눅스 x64에서
맥에서 npm install
darwin
Could not load linux-x64
optional 생략
껍데기만
같은 문장. @img가 비어 있음
--libc=musl만 받음
linuxmusl
glibc 이미지에서는 여전히 실패
배포가 도는 기계와 노트북의 CPU·라이브러리가 다르면 바이너리도 달라야 합니다
번들과 압축 파일이 네이티브를 버린다
파일을 받아도 번들러가 sharp를 안으로 넣으면 .node가 빠집니다.
웹팩은 externals에 sharp: 'commonjs sharp', esbuild와 비트는 external에 sharp를 둡니다. 넥스트는 serverExternalPackages에 sharp를 넣어 서버 번들이 그 패키지를 복사 대상으로 남기게 합니다. 스탠드얼론 출력에서 패키지 자체가 없다는 넥스트 문구(sharp가 프로덕션에 필요)는 트레이서가 폴더를 빠뜨린 줄이라, linux-x64를 못 읽는 줄과 다릅니다.
람다 배포 압축에는 고른 아키텍처의 linux-x64 또는 linux-arm64 바이너리가 들어 있어야 합니다. 일부 매니저는 심볼릭 링크로 optional 패키지를 연결하는데, 람다는 배포 압축 안의 심볼릭 링크를 지원하지 않습니다. 맥 node_modules를 zip으로 올리면 다윈 파일만 들어갑니다. 압축 전에 대상 플랫폼으로 설치합니다.
전역 libvips를 쓰려면 config.libvips 이상이고 pkg-config --modversion vips-cpp로 보여야 합니다. 윈도우와, 로제타로 도는 맥의 노드에서는 전역 libvips가 지원되지 않습니다. 기본 경로는 sharp가 같이 주는 바이너리입니다.
이미지 코드를 고치기 전에 볼 순서
리사이즈 옵션보다 바이너리 폴더가 먼저입니다.
로그의 런타임을 그대로 적습니다. linux-x64인지 linuxmusl-x64인지 linux-arm64인지.
배포와 같은 환경에서 node -v가 20.9.0 이상인지 봅니다. Node-API v9 미만이면 프리빌드가 안 맞습니다.
node_modules/@img에 그 플랫폼 패키지가 있는지 봅니다. 없으면 --include=optional과 os, cpu, libc로 다시 설치합니다.
락 파일을 맥과 리눅스가 공유하면 npm 4828을 의심하고, 필요한 플랫폼이 락에 들어갔는지 확인합니다.
웹팩·esbuild·비트·넥스트가 sharp를 번들 밖으로 두었는지 봅니다.
람다면 압축 안에 심볼릭 링크가 없는지, 대상 아키텍처 파일이 들어 있는지 봅니다.
문장이 모듈 호환 숫자이거나 엣지 거절이면 엣지 모듈과 엔진 파일 누락처럼 다른 네이티브 글로 갑니다. 리사이즈 인자는 그다음에 봅니다.
한국에서 맥북으로 개발하고 버셀 프리뷰에 올리는 경우, 낮에는 썸네일 생성이 되고 배포 함수만 실행 파일을 못 찾습니다. 카카오 프로필 사진을 받아 크기를 줄이는 라우트가 그 예입니다. 선택 의존을 끈 설치 명령이 자동 빌드에 남아 있으면, 같은 명령을 배포에서 다시 해도 껍데기만 받습니다. 로그의 플랫폼 이름과 받은 폴더 이름이 같은지 본 다음에 화질 옵션을 고칩니다.
확인한 문서
플랫폼 최소선과 설치 플래그는 sharp 설치 페이지를 정본으로 둡니다. 2026-10-06에 확인했습니다.
프리빌드가 있는 플랫폼이면 먼저 그 파일을 받습니다. 소스 빌드는 C++17, node-addon-api 7 이상, node-gyp 9 이상이 필요합니다. 전역 libvips를 찾을 때만 SHARP_IGNORE_GLOBAL_LIBVIPS로 건너뜁니다.
sharp의 linux-x64 Could not load는 그 플랫폼 바이너리가 배포 폴더에 없다는 뜻입니다. 로그의 OS·CPU·libc와 @img 폴더를 맞추고, 번들이 네이티브를 삼키지 않았는지 보세요. ABI가 다른 dlopen이나 엣지 거절과는 다음 명령이 다릅니다. 관련 글: 프리즈마 엔진 파일, 엣지 런타임의 노드 모듈, 모듈을 못 찾는 줄.