๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๊ฐœ๋ฐœ/AWS

Docker๋กœ Lambda ์ด๋ฏธ์ง€ ๋งŒ๋“ค์–ด ๋ฐฐํฌํ•˜๊ธฐ

๋ฐ˜์‘ํ˜•

๐Ÿ“„ ๋ชฉ์ฐจ

1. ํ”„๋กœ์ ํŠธ ์ค€๋น„

๋นˆ ํ”„๋กœ์ ํŠธ์— package.json, app.js, Dockefile์„ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ์ผ๋‹จ ๋นˆ ๋žŒ๋‹ค๋ฅผ Dockerizeํ•ด์„œ ์˜ฌ๋ ค๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Dockerfile

FROM public.ecr.aws/lambda/nodejs:18

# Assumes your function is named "app.js", and there is a package.json file in the app directory 
COPY app.js package.json  ${LAMBDA_TASK_ROOT}/

# Install NPM dependencies for function
RUN npm install

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.handler" ]

app.js

exports.handler = async function (event, context) {
  console.log("EVENT: \n" + JSON.stringify(event, null, 2));
  return {
    statusCode: 200,
    body: {
      data: "hi",
    },
  };
};

package.json

{
  "name": [ํ”„๋กœ์ ํŠธ ์ด๋ฆ„], // "ffmpeg-lambda",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

2. ๋นŒ๋“œ

๋นŒ๋“œํ•ด์„œ ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

# ๋„์ปค ๋นŒ๋“œ
docker build --platform linux/amd64 -t [๋„์ปค์ด๋ฏธ์ง€๋ช…] .
# docker build --platform linux/amd64 -t audio-process-lambda .

๋นŒ๋“œํ•œ ์ปจํ…Œ์ด๋„ˆ๋Š” ๋กœ์ปฌ์—์„œ ์‹คํ–‰์‹œ์ผœ ํ…Œ์ŠคํŠธํ•ด๋ด…๋‹ˆ๋‹ค.

# ๋„์ปค ์‹คํ–‰
docker run -p 9000:8080 [๋„์ปค์ด๋ฏธ์ง€]
# docker run -p 9000:8080 audio-process-lambda

ํ˜ธ์ถœ์€ ์•„๋ž˜ ๊ฒฝ๋กœ๋กœ ํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
# ์‘๋‹ต : {"statusCode":200,"body":{"data":"hi"}}

 

์ •์ƒ ์‘๋‹ต์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ์ด ๊ธฐ๋ณธ๋žŒ๋‹ค๋ฅผ AWS Lambda์— ๋ฐฐํฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

3. ECR ์ƒ์„ฑ

๋„์ปค ์ด๋ฏธ์ง€๋ฅผ ์œ„ํ•œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์ธ ECR์„ ์ƒ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ด๋ฆ„๋งŒ ๋ช…์‹œํ•ด์ฃผ๊ณ  ๋‚˜๋จธ์ง€๋Š” ๋‹ค ๊ธฐ๋ณธ ์˜ต์…˜์œผ๋กœ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

์ƒ์„ฑ๋œ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋กœ ๋“ค์–ด๊ฐ€๋ฉด ์ด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•˜๊ธฐ ์œ„ํ•œ ํ‘ธ์‹œ ๋ช…๋ น์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ช…๋ น ๊ทธ๋Œ€๋กœ ์ด๋ฏธ์ง€๋ฅผ ํ‘ธ์‹œํ•ด์ฃผ๋ฉด latest ์ด๋ฏธ์ง€๊ฐ€ ECR์— ์˜ฌ๋ผ๊ฐ„ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค..

aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin [๋น„๋ฒˆ]
docker tag audio-process-lambda:latest [๊ณ„์ •id].dkr.ecr.ap-northeast-2.amazonaws.com/audio-process-lambda:latest
docker push [๊ณ„์ •id].dkr.ecr.ap-northeast-2.amazonaws.com/audio-process-lambda:latest

 

4. ๋žŒ๋‹ค ์ƒ์„ฑ

์ด์ œ ์ด ์ด๋ฏธ์ง€๋กœ ๋žŒ๋‹ค๋ฅผ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. 

- Container image์—์„œ ์ƒ์„ฑ ์˜ต์…˜ ์„ ํƒ

- ์•„๊นŒ ํ‘ธ์‹œํ•œ ECR ์— ์žˆ๋Š” ์ด๋ฏธ์ง€ ์„ ํƒ

- Architecture : ๋นŒ๋“œ์— ์‚ฌ์šฉํ•œ ์ •๋ณด ์„ ํƒ 

๋ฐฐํฌ ์™„๋ฃŒ๋˜๋ฉด ๋žŒ๋‹ค์˜ Testํƒญ์„ ํ†ตํ•ด ์‘๋‹ต์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

โš ๏ธ  Architecture ์„ ํƒ๊ณผ  Runtime.InvalidEntryPoint ์˜ค๋ฅ˜

MAC M1 ์—์„œ ๋นŒ๋“œ ํ›„ x86_64 ์˜ต์…˜์œผ๋กœ ๋žŒ๋‹ค๋ฅผ ๋ฐฐํฌํ•˜๋ฉด ์‹คํ–‰์ด ๋˜์ง€ ์•Š๊ณ  ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

๊ผญ ๋นŒ๋“œํ•œ ์ •๋ณด์™€ ๋ฐฐํฌํ•  ํ™˜๊ฒฝ์„ ๋งž์ถฐ์ฃผ์„ธ์š” 

{
  "errorType": "Runtime.InvalidEntrypoint",
  "errorMessage": "RequestId: d35cad28-680b-428c-be4a-182f5d8bcdff Error: fork/exec /lambda-entrypoint.sh: exec format error"
}

For anyone visiting this, the problem could also be due to the fact that the image has been built on a different CPU architecture than specified on AWS. For example, if you have built your image on an M1, you have to choose the option of arm64 in lambda image dialog.

 

 

๋ฐ˜์‘ํ˜•