람다와 ARM 아키텍처 오류 해결

devyu·2024년 6월 3일
0

AWS

목록 보기
1/4
post-thumbnail

해당 포스트는 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 를 활용하여 마침내 문제를 해결할 수 있었다.

문제 해결

아래는 문제 해결 과정이다.

1. package.json 작성

아래 이미지처럼 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"
  }
}

2. Dockerfile 작성

다음으로 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 부분이다.

3. Docker Buildx 설정 및 빌드

docker buildx를 사용하여 linux/amd64 플랫폼용으로 이미지를 빌드하고 실행한다.

docker buildx create --use
docker buildx inspect --bootstrap

docker buildx build --platform linux/amd64 -t my-lambda-function --load .

4. Docker 컨테이너 실행 및 모듈 추출

빌드한 이미지를 실행하여 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가 생성된다.

5. 마무리 - 압축

이제 작업중인 디렉토리에서 node_modules 폴더, package.json, index.js(여기서 이 파일은 람다 실행을 위한 함수 코드 내용이다)와 같이 람다에 업로드하기 위한 파일이 모두 준비된다. 이 셋을 모두 압축하여 람다에 업로드한다.

2시간만에 드디어 성공했다....🥲

profile
티스토리와 벨로그 사이 줄타기....

0개의 댓글