本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
使用容器映像在 Lambda 中部署轉換的 TypeScript 程式碼
您可以將 TypeScript 程式碼作為 Node.js 容器映像部署至 AWS Lambda 函數。AWS 提供 Node.js 的基礎映像來協助您建置容器映像。這些基礎映像會預先載入語言執行時間以及在 Lambda 上執行映像所需的其他元件。AWS 會為每個基礎映像提供一個 Dockerfile,以幫助建置容器映像。
如果您使用社群或私有企業基礎映像,必須將 Node.js 執行時間介面用戶端 (RIC) 新增至基礎映像,以使其與 Lambda 相容。
Lambda 提供執行期介面模擬器,供您在本機測試函數。Node.js 的 AWS 基礎映像包含執行期界面模擬器。如果您使用替代基礎映像 (例如 Alpine Linux 或 Debian 映像),便可 將模擬器建置到映像中
使用 Node.js 基礎映像來建置和封裝 TypeScript 函數程式碼
若要完成本節中的步驟,您必須執行下列各項:
-
Docker
(最低版本 25.0.0) -
Docker buildx 外掛程式
。 -
Node.js 22.x
若要從 AWS 基礎映像中建立 Lambda 的映像
-
在您的本機電腦上,為新函數建立專案目錄。
-
建立具有
npm的新 Node.js 專案,或您選擇的套件管理員。npm init -
新增 @types/aws-lambda
和 esbuild 套件作為開發相依項。 @types/aws-lambda套件包含 Lambda 的類型定義。npm install -D @types/aws-lambda esbuild -
將建置指令碼
新增至 package.json檔案。"scripts": { "build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2020 --outfile=dist/index.js" } -
建立稱為
index.ts的新檔案。將下列範本程式碼新增至新檔案。這是 Lambda 函數的程式碼。該函數會傳回hello world訊息。注意
import陳述式會從 @types/aws-lambda中匯入類型定義。不會匯入 aws-lambdaNPM 套件,這是不相關的第三方工具。如需詳細資訊,請參閱 DefinitelyTyped GitHub 儲存庫中的 aws-lambda。 import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; export const handler = async (event: APIGatewayEvent, context: Context): Promise<APIGatewayProxyResult> => { console.log(`Event: ${JSON.stringify(event, null, 2)}`); console.log(`Context: ${JSON.stringify(context, null, 2)}`); return { statusCode: 200, body: JSON.stringify({ message: 'hello world', }), }; }; -
建立包含下列組態的新 Dockerfile。
-
將
FROM屬性設定為基礎映像的 URI。 -
設定
CMD引數以指定 Lambda 函數處理常式。
下列範例 Dockerfile 使用多階段建置。第一步將 TypeScript 程式碼轉換為 JavaScript。第二步產生僅包含 JavaScript 檔案和生產相依項的容器映像。
請注意,範例 Dockerfile 不包含 USER 指令
。當您將容器映像部署到 Lambda 時,Lambda 會自動定義一個具有最低權限許可的預設 Linux 使用者。這與標準 Docker 行為不同,後者會在未提供 USER指令時預設為root使用者。範例 Dockerfile
FROM public.ecr.aws/lambda/nodejs:22 as builder WORKDIR /usr/app COPY package.json index.ts ./ RUN npm install RUN npm run build FROM public.ecr.aws/lambda/nodejs:22 WORKDIR ${LAMBDA_TASK_ROOT} COPY --from=builder /usr/app/dist/* ./ CMD ["index.handler"] -
-
使用 docker build
命令建立 Docker 映像檔。以下範例將映像命名為 docker-image並為其提供test標籤。若要使映像與 Lambda 相容,必須使用 --provenance=false選項。docker buildx build --platform linux/amd64 --provenance=false -tdocker-image:test.注意
此命令會指定
--platform linux/amd64選項,確保無論建置機器的架構為何,您的容器都與 Lambda 執行環境相容。如果您打算使用 ARM64 指令集架構建立 Lambda 函數,務必將命令變更為改用--platform linux/arm64選項。
-
使用 docker run 命令啟動 Docker 影像。在此範例中,
docker-image為映像名稱,test為標籤。docker run --platform linux/amd64 -p 9000:8080docker-image:test此命令將映像作為容器執行,並在
localhost:9000/2015-03-31/functions/function/invocations建立本機端點。注意
如果您為 ARM64 指令集架構建立 Docker 映像檔,請務必將
--platform linux/選項改用選項。arm64--platform linux/amd64 -
從新的終端機視窗,將事件張貼至本機端點。
-
取得容器 ID。
docker ps -
使用 docker kill
命令停止容器。在此命令中,將 3766c4ab331c替換為上一步驟中的容器 ID。docker kill3766c4ab331c
若要將映像上傳至 Amazon ECR 並建立 Lambda 函數
-
使用 get-login-password
命令,向 Amazon ECR 登錄檔驗證 Docker CLI。 -
將
--region值設定為您要在其中建立 Amazon ECR 儲存庫的 AWS 區域。 -
用您的 AWS 帳戶 ID 取代
111122223333。
aws ecr get-login-password --regionus-east-1| docker login --username AWS --password-stdin111122223333.dkr.ecr.us-east-1.amazonaws.com -
-
使用 create-repository
命令在 Amazon ECR 中建立儲存庫。 aws ecr create-repository --repository-namehello-world--regionus-east-1--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE注意
Amazon ECR 儲存庫必須位於與 Lambda 函數相同的 AWS 區域 中。
如果成功,您將會看到以下回應:
{ "repository": { "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world", "registryId": "111122223333", "repositoryName": "hello-world", "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world", "createdAt": "2023-03-09T10:39:01+00:00", "imageTagMutability": "MUTABLE", "imageScanningConfiguration": { "scanOnPush": true }, "encryptionConfiguration": { "encryptionType": "AES256" } } } -
從上一步驟的輸出中複製
repositoryUri。 -
執行 docker tag
命令,將 Amazon ECR 儲存庫中的本機映像標記為最新版本。在此命令中: -
docker-image:test為 Docker 映像檔的名稱和標籤。這是您在 docker build命令中指定的映像名稱和標籤。 -
將
<ECRrepositoryUri>替換為複製的repositoryUri。確保在 URI 的末尾包含:latest。
docker tag docker-image:test<ECRrepositoryUri>:latest範例:
docker tagdocker-image:test111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest -
-
執行 docker push
命令,將本機映像部署至 Amazon ECR 儲存庫。確保在儲存庫 URI 的末尾包含 :latest。docker push111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest -
建立函數的執行角色 (若您還沒有的話)。在下一個步驟中您需要角色的 Amazon Resource Name (ARN)。
-
建立 Lambda 函數。對於
ImageUri,從之前的設定中指定儲存庫 URI。確保在 URI 的末尾包含:latest。aws lambda create-function \ --function-namehello-world\ --package-type Image \ --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \ --rolearn:aws:iam::111122223333:role/lambda-ex注意
只要映像檔與 Lambda 函數位於相同的區域,您就可以使用不同 AWS 帳戶中的映像檔建立函數。如需更多詳細資訊,請參閱 Amazon ECR 跨帳戶許可。
-
調用函數。
aws lambda invoke --function-namehello-worldresponse.json您應該看到如下回應:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 } -
若要查看函數的輸出,請檢查
response.json檔案。
若要更新函數程式碼,您必須再次建置映像、將新映像上傳到 Amazon ECR 存放庫,然後使用 update-function-code
Lambda 會將映像標籤解析為特定映像摘要。這表示如果您將用來部署函數的映像標籤指向 Amazon ECR 中的新映像,Lambda 不會自動更新函數以使用新映像。
若要將新映像部署至相同的 Lambda 函數,必須使用 update-function-code--publish 選項會使用更新的容器映像來建立新的函數版本。
aws lambda update-function-code \ --function-namehello-world\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest\ --publish