해당 포스트는 AWS Lambda x86_64 아키텍처를 ARM 기반의 로컬에서 작성하시는 분들 중 같은 오류(Cannot find module / Could not load module) 를 겪는 분들을 위해 작성되었습니다.
| sharp 모듈 설치 과정에서 오류 발생
오류 코드 전문
{
"errorType": "Error",
"errorMessage": "Could not load the \"sharp\" module using the linux-x64 runtime\nPossible solutions:\n- Ensure optional dependencies can be installed:\n npm install --include=optional sharp\n yarn add sharp --ignore-engines\n- Ensure your package manager supports multi-platform installation:\n See https://sharp.pixelplumbing.com/install#cross-platform\n- Add platform-specific dependencies:\n npm install --os=linux --cpu=x64 sharp\n- Consult the installation documentation:\n See https://sharp.pixelplumbing.com/install",
"stack": [
"Error: Could not load the \"sharp\" module using the linux-x64 runtime",
"Possible solutions:",
"- Ensure optional dependencies can be installed:",
" npm install --include=optional sharp",
" yarn add sharp --ignore-engines",
"- Ensure your package manager supports multi-platform installation:",
" See https://sharp.pixelplumbing.com/install#cross-platform",
"- Add platform-specific dependencies:",
" npm install --os=linux --cpu=x64 sharp",
"- Consult the installation documentation:",
" See https://sharp.pixelplumbing.com/install",
" at Object.<anonymous> (/var/task/node_modules/sharp/lib/sharp.js:114:9)",
" at Module._compile (node:internal/modules/cjs/loader:1358:14)",
" at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)",
" at Module.load (node:internal/modules/cjs/loader:1208:32)",
" at Module._load (node:internal/modules/cjs/loader:1024:12)",
" at Module.require (node:internal/modules/cjs/loader:1233:19)",
" at require (node:internal/modules/helpers:179:18)",
" at Object.<anonymous> (/var/task/node_modules/sharp/lib/constructor.js:10:1)",
" at Module._compile (node:internal/modules/cjs/loader:1358:14)",
" at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)"
]
}
내 맥은 m1이라 arm 기반인데 람다 함수에서 해당 모듈 설치가 계속 제대로 되지 않았다. 아키텍처 문제임을 확신하게 된 것은
위처럼 람다의 아키텍처를 arm64로 설정하여 모듈 설치시 정상적으로 테스트를 통과했기 때문이다. (하지만 Lambda@Edge에서는 arm64 사용이 불가능해 x86_64로 무조건 진행해야 하는 상황이었다.)
npm uninstall sharp
로 모두 삭제하고
npm install --platform=linux --arch=x64 sharp
npm install --arch=x64 --platform=linux sharp
등 가능한 명령어들은 다 해보고, 재설치는 물론 package.json도 다시 작성하였지만, 여전히 같은 오류가 발생하고 있었다.
docker 로 말아도 여전히 문제가 있었는데(build 사용..), buildx
를 활용하여 마침내 문제를 해결할 수 있었다.
아래는 문제 해결 과정이다.
아래 이미지처럼 aws-sdk와 sharp 두 모듈에서 문제가 발생하고 있었기 때문에 package.json에 두 모듈을 작성했다.
오류 코드 전문
{
"errorType": "Runtime.ImportModuleError",
"errorMessage": "Error: Cannot find module 'aws-sdk'\nRequire stack:\n- /var/task/index.js\n- /var/runtime/index.mjs",
"stack": [
"Runtime.ImportModuleError: Error: Cannot find module 'aws-sdk'",
"Require stack:",
"- /var/task/index.js",
"- /var/runtime/index.mjs",
" at _loadUserApp (file:///var/runtime/index.mjs:1087:17)",
" at async UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:1119:21)",
" at async start (file:///var/runtime/index.mjs:1282:23)",
" at async file:///var/runtime/index.mjs:1288:1"
]
}
package.json
{
"name": "my-lambda-function",
"version": "1.0.0",
"description": "My Lambda Function",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"sharp": "^0.29.0",
"aws-sdk": "^2.814.0"
}
}
다음으로 sharp 및 aws-sdk 모듈을 설치할 Dockerfile을 작성하였다.
Dockerfile
# syntax=docker/dockerfile:1
FROM node:14
WORKDIR /usr/src/app
COPY package.json package-lock.json* ./
RUN npm install --arch=x64 --platform=linux
COPY . .
CMD ["bash"]
노드 버전 등 나머지 사항은 본인의 세팅에 맞춰 변경하면 된다. 핵심은 RUN npm install --arch=x64 --platform=linux
부분이다.
docker buildx를 사용하여 linux/amd64 플랫폼용으로 이미지를 빌드하고 실행한다.
docker buildx create --use
docker buildx inspect --bootstrap
docker buildx build --platform linux/amd64 -t my-lambda-function --load .
빌드한 이미지를 실행하여 node_modules 디렉토리를 추출한다. 이때 my-lambda-function은 현재 작업중인 디렉토리의 이름이다. (index.js 와 package.json 파일이 있는 디렉토리)
docker run --rm -it -v $(pwd)/output:/output my-lambda-function bash
접속 후에는 아래 명령어를 통해 로컬 시스템의 output 디렉토리에 node_modules.tar.gz 파일을 생성한다.
cd /usr/src/app
tar -czvf /output/node_modules.tar.gz node_modules
그 후에는 아래처럼 exit를 통해 컨테이너를 나간다.
이제 람다 함수를 위한 패키징을 진행한다. 아래 명령어를 통해node_modules.tar.gz 파일을 my-lambda-function 디렉토리에 압축 해제한다.
mkdir -p my-lambda-function/node_modules
tar -xzvf output/node_modules.tar.gz -C my-lambda-function
이렇게 하면, my-lambda-function 디렉토리 내에 node_modules가 생성된다.
이제 작업중인 디렉토리에서 node_modules 폴더, package.json, index.js(여기서 이 파일은 람다 실행을 위한 함수 코드 내용이다)와 같이 람다에 업로드하기 위한 파일이 모두 준비된다. 이 셋을 모두 압축하여 람다에 업로드한다.
2시간만에 드디어 성공했다....🥲