Bereitstellen von Node.js-Lambda-Funktionen mit Container-Images
Es gibt drei Möglichkeiten, ein Container-Image für eine Node.js-Lambda-Funktion zu erstellen:
-
Ein AWS-Basisimage für Node.js verwenden
Die AWS-Basis-Images sind mit einer Sprachlaufzeit, einem Laufzeitschnittstellen-Client zur Verwaltung der Interaktion zwischen Lambda und Ihrem Funktionscode und einem Laufzeitschnittstellen-Emulator für lokale Tests vorinstalliert.
-
Verwenden eines reinen AWS-OS-Basis-Image
AWS-OS-Basis-Images
enthalten eine Amazon-Linux-Distribution und den Laufzeitschnittstellen-Emulator . Diese Images werden häufig verwendet, um Container-Images für kompilierte Sprachen wie Go und Rust sowie für eine Sprache oder Sprachversion zu erstellen, für die Lambda kein Basis-Image bereitstellt, wie Node.js 19. Sie können reine OS-Basis-Images auch verwenden, um eine benutzerdefinierte Laufzeit zu implementieren. Um das Image mit Lambda kompatibel zu machen, müssen Sie den Laufzeitschnittstellen-Client für Node.js in das Image aufnehmen. -
Verwenden eines Nicht-AWS-Basis-Images
Sie können auch ein alternatives Basis-Image aus einer anderen Container-Registry verwenden. Sie können auch ein von Ihrer Organisation erstelltes benutzerdefiniertes Image verwenden. Um das Image mit Lambda kompatibel zu machen, müssen Sie den Laufzeitschnittstellen-Client für Node.js in das Image aufnehmen.
Tipp
Um die Zeit zu reduzieren, die benötigt wird, bis Lambda-Container-Funktionen aktiv werden, siehe die Docker-Dokumentation unter Verwenden mehrstufiger Builds
Auf dieser Seite wird erklärt, wie Sie Container-Images für Lambda erstellen, testen und bereitstellen.
Themen
AWS-Basis-Images für Node.js
AWS stellt die folgenden Basis-Images für Node.js bereit:
| Tags | Laufzeit | Betriebssystem | Dockerfile | Ablehnung |
|---|---|---|---|---|
22 |
Node.js 22 | Amazon Linux 2023 | Docker-Datei für Node.js 22 auf GitHub |
30. Apr 2027 |
20 |
Node.js 20 | Amazon Linux 2023 | Docker-Datei für Node.js 20 auf GitHub |
30. Apr 2026 |
Amazon-ECR-Repository: gallery.ecr.aws/lambda/nodejs
Die Basis-Images für Node.js 20 und höher basieren auf dem Amazon Linux 2023 Minimal Container Image. Frühere Basis-Images verwenden Amazon Linux 2. AL2023 bietet mehrere Vorteile gegenüber Amazon Linux 2, darunter einen geringeren Bereitstellungsaufwand und aktualisierte Versionen von Bibliotheken wie glibc.
AL2023-basierte Bilder verwenden microdnf (symbolisiert als dnf) als Paketmanager anstelle von yum, was der Standard-Paketmanager in Amazon Linux 2 ist. microdnf ist eine eigenständige Implementierung von dnf. Eine Liste der Pakete, die in AL2023-basierte Bilder enthalten sind, finden Sie in den Spalten mit dem Namen Minimal Container unter Comparing packages installed on Amazon Linux 2023 Container Images. Weitere Informationen zu den Unterschieden zwischen AL2023 und Amazon Linux 2 finden Sie unter Introducing the Amazon Linux 2023 runtime for AWS Lambda
Anmerkung
Um AL2023-basierte Images lokal auszuführen, auch mit AWS Serverless Application Model (AWS SAM), müssen Sie Docker-Version 20.10.10 oder höher verwenden.
Ein AWS-Basisimage für Node.js verwenden
Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie Folgendes:
-
Docker
(Mindestversion 25.0.0) -
Das Docker-buildx-Plugin
. -
Node.js
So erstellen Sie ein Container-Image aus einem AWS-Basis-Image für Node.js
-
Erstellen Sie ein Verzeichnis für das Projekt und wechseln Sie dann zu diesem Verzeichnis.
mkdir example cd example -
Erstellen Sie ein neues Node.js-Projekt mit
npm. Um die im interaktiven Erlebnis bereitgestellten Standardoptionen zu akzeptieren, drücken SieEnter.npm init -
Erstellen Sie eine neue Datei mit dem Namen
index.js. Sie können der Datei zum Testen den folgenden Beispielfunktionscode hinzufügen oder Ihren eigenen verwenden.Beispiel CommonJS-Handler
exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; }; -
Wenn Ihre Funktion von anderen Bibliotheken als der AWS SDK für JavaScript abhängt, verwenden Sie npm
, um sie zu Ihrem Paket hinzuzufügen. -
Erstellen Sie eine neue Docker-Datei mit der folgenden Konfiguration:
-
Setzen Sie die
FROM-Eigenschaft auf den URI des Basis-Images. -
Verwenden Sie den Befehl COPY, um den Funktionscode und die Laufzeitabhängigkeiten in
{LAMBDA_TASK_ROOT}, eine von Lambda definierte Umgebungsvariable zu kopieren. -
Legen Sie das
CMD-Argument auf den Lambda-Funktionshandler fest.
Beachten Sie, dass das Dockerfile-Beispiel keine USER-Anweisung
enthält. Wenn Sie ein Container-Image für Lambda bereitstellen, definiert Lambda automatisch einen Standard-Linux-Benutzer mit Berechtigungen mit geringsten Rechten. Dies unterscheidet sich vom Standardverhalten von Docker, bei dem standardmäßig der root-Benutzer verwendet wird, wenn keineUSER-Anweisung bereitgestellt wird.Beispiel Dockerfile
FROMpublic.ecr.aws/lambda/nodejs:22# Copy function code COPYindex.js${LAMBDA_TASK_ROOT} # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile) CMD [ "index.handler" ] -
-
Erstellen Sie Ihr Docker-Image mit dem docker build
-Befehl. Das folgende Beispiel benennt das Bild in docker-imageund gibt ihm dentestTag. Um Ihr Image mit Lambda kompatibel zu machen, müssen Sie die Option --provenance=falseverwenden.docker buildx build --platform linux/amd64 --provenance=false -tdocker-image:test.Anmerkung
Der Befehl gibt die
--platform linux/amd64-Option an, um sicherzustellen, dass Ihr Container mit der Lambda-Ausführungsumgebung kompatibel ist, unabhängig von der Architektur des Entwicklungsrechners. Wenn Sie beabsichtigen, eine Lambda-Funktion mithilfe der ARM64-Befehlssatzarchitektur zu erstellen, müssen Sie den Befehl unbedingt so ändern, dass stattdessen die--platform linux/arm64-Option verwendet wird.
-
Starten Sie Ihr Docker-Image mit dem docker run-Befehl. In diesem Beispiel ist
docker-imageder Image-Name undtestder Tag.docker run --platform linux/amd64 -p 9000:8080docker-image:testDieser Befehl führt das Image als Container aus und erstellt einen lokalen Endpunkt bei
localhost:9000/2015-03-31/functions/function/invocations.Anmerkung
Wenn Sie das Docker-Image für die ARM64-Befehlssatz-Architektur erstellt haben, müssen Sie die Option
--platform linux/stattarm64--platform linux/verwenden.amd64 -
Veröffentlichen Sie in einem neuen Terminalfenster ein Ereignis an den lokalen Endpunkt.
-
Die Container-ID erhalten.
docker ps -
Verwenden Sie den Befehl docker kill
, um den Container zu anzuhalten. Ersetzen Sie in diesem Befehl 3766c4ab331cdurch die Container-ID aus dem vorherigen Schritt.docker kill3766c4ab331c
Um das Image in Amazon ECR hochzuladen und die Lambda-Funktion zu erstellen
-
Führen Sie den Befehl get-login-password
aus, um die Docker-CLI bei Ihrem Amazon-ECR-Registry zu authentifizieren. -
Stellen Sie den
--regionWert auf die AWS-Region ein, in der Sie das Amazon-ECR-Repository erstellen möchten. -
Ersetzen Sie
111122223333mit Ihrer AWS-Konto-ID.
aws ecr get-login-password --regionus-east-1| docker login --username AWS --password-stdin111122223333.dkr.ecr.us-east-1.amazonaws.com -
-
Erstellen Sie ein Repository in Amazon ECR mithilfe des Befehls create-repository
. aws ecr create-repository --repository-namehello-world--regionus-east-1--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLEAnmerkung
Das Amazon ECR-Repository muss sich im selben AWS-Region wie die Lambda-Funktion befinden.
Wenn erfolgreich, sehen Sie eine Antwort wie diese:
{ "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" } } } -
Kopieren Sie das
repositoryUriaus der Ausgabe im vorherigen Schritt. -
Führen Sie den Befehl docker tag
aus, um Ihr lokales Image als neueste Version in Ihrem Amazon-ECR-Repository zu markieren. In diesem Befehl gilt Folgendes: -
docker-image:testist der Name und das TagIhres Docker-Images. Dies sind der Imagename und das Tag, die Sie im docker build-Befehl angegeben haben. -
Ersetzen Sie
<ECRrepositoryUri>durch denrepositoryUri, den Sie kopiert haben. Stellen Sie sicher, dass Sie:latestam Ende der URI angeben.
docker tag docker-image:test<ECRrepositoryUri>:latestBeispiel:
docker tagdocker-image:test111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest -
-
Führen Sie den Befehl docker push
aus, um Ihr lokales Image im Amazon-ECR-Repository bereitzustellen. Stellen Sie sicher, dass Sie :latestam Ende der Repository-URI angeben.docker push111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest -
Erstellen Sie eine Ausführungsrolle für die Funktion, wenn Sie noch keine haben. Sie benötigen den Amazon-Ressourcennamen (ARN) der Rolle im nächsten Schritt.
-
So erstellen Sie die Lambda-Funktion: Geben Sie für
ImageUridie Repository-URI von zuvor an. Stellen Sie sicher, dass Sie:latestam Ende der URI angeben.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-exAnmerkung
Sie können eine Funktion mit einem Bild in einem anderen AWS-Konto erstellen, sofern sich das Bild in derselben Region wie die Lambda-Funktion befindet. Weitere Informationen finden Sie unter Kontoübergreifende Berechtigungen von Amazon ECR.
-
Die Funktion aufrufen.
aws lambda invoke --function-namehello-worldresponse.jsonDas Ergebnis sollte ungefähr wie folgt aussehen:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 } -
Um die Ausgabe der Funktion zu sehen, überprüfen Sie die
response.json-Datei.
Um den Funktionscode zu aktualisieren, müssen Sie das Image erneut erstellen, das neue Image in das Amazon-ECR-Repository hochladen und dann den Befehl update-function-code
Lambda löst das Image-Tag in einen bestimmten Image-Digest auf. Das heißt, wenn Sie das Image-Tag, das zur Bereitstellung der Funktion verwendet wurde, auf ein neues Image in Amazon ECR verweisen, aktualisiert Lambda die Funktion nicht automatisch, um das neue Image zu verwenden.
Um das neue Image für dieselbe Lambda-Funktion bereitzustellen, müssen Sie den Befehl update-function-code--publish-Option eine neue Version der Funktion unter Verwendung des aktualisierten Container-Images.
aws lambda update-function-code \ --function-namehello-world\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest\ --publish
Verwenden eines alternativen Basis-Images mit dem Laufzeitschnittstellen-Client
Wenn Sie ein OS-Basis-Image oder ein alternatives Basis-Image verwenden, müssen Sie den Laufzeitschnittstellen-Client in das Image einbinden. Der Laufzeitschnittstellen-Client erweitert die Laufzeit-API, die die Interaktion zwischen Lambda und Ihrem Funktionscode verwaltet.
Installieren Sie den Laufzeitschnittstellen-Client für Node.js
npm install aws-lambda-ric
Sie können auch den Node.js-Laufzeitschnittstellen-Client
Das folgende Beispiel zeigt, wie Sie mithilfe eines Nicht-AWS-Basis-Images ein Container-Image für Node.js erstellen. Das Beispiel-Dockerfile verwendet ein bookworm-Basis-Image. Das Docker-File enthält den Laufzeitschnittstellen-Client.
Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie Folgendes:
-
Docker
(Mindestversion 25.0.0) -
Das Docker-buildx-Plugin
. -
Node.js
Erstellen eines Container-Images aus einem Nicht-AWS-Basis-Image
-
Erstellen Sie ein Verzeichnis für das Projekt und wechseln Sie dann zu diesem Verzeichnis.
mkdir example cd example -
Erstellen Sie ein neues Node.js-Projekt mit
npm. Um die im interaktiven Erlebnis bereitgestellten Standardoptionen zu akzeptieren, drücken SieEnter.npm init -
Erstellen Sie eine neue Datei mit dem Namen
index.js. Sie können der Datei zum Testen den folgenden Beispielfunktionscode hinzufügen oder Ihren eigenen verwenden.Beispiel CommonJS-Handler
exports.handler = async (event) => { const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), }; return response; }; -
Erstellen Sie eine neue Docker-Datei. Das folgende Dockerfile verwendet ein
bookworm-Basis-Image anstelle eines AWS-Basis-Images. Das Dockerfile enthält den Laufzeitschnittstellen-Client, der das Image mit Lambda kompatibel macht. Das folgende Dockerfile verwendet einen Build mit mehreren Phasen . In der ersten Phase wird ein Build-Image erstellt, bei dem es sich um eine Standardumgebung von Node.js handelt, in der die Abhängigkeiten der Funktion installiert werden. In der zweiten Phase wird ein schlankeres Image erstellt, das den Funktionscode und seine Abhängigkeiten enthält. Dadurch wird die endgültige Image-Größe reduziert. -
Legen Sie
FROM-Eigenschaft auf die Kennung des Basis-Images fest. -
Verwenden Sie den Befehl
COPY, um den Funktionscode und die Laufzeitabhängigkeiten zu kopieren. -
Legen Sie
ENTRYPOINTauf das Modul fest, das der Docker-Container beim Start ausführen soll. In diesem Fall ist das Modul der Laufzeitschnittstellen-Client. -
Legen Sie das
CMD-Argument auf den Lambda-Funktionshandler fest.
Beachten Sie, dass das Dockerfile-Beispiel keine USER-Anweisung
enthält. Wenn Sie ein Container-Image für Lambda bereitstellen, definiert Lambda automatisch einen Standard-Linux-Benutzer mit Berechtigungen mit geringsten Rechten. Dies unterscheidet sich vom Standardverhalten von Docker, bei dem standardmäßig der root-Benutzer verwendet wird, wenn keineUSER-Anweisung bereitgestellt wird.Beispiel Dockerfile
# Define custom function directory ARG FUNCTION_DIR="/function" FROMnode:20-bookwormas build-image # Include global arg in this stage of the build ARG FUNCTION_DIR # Install build dependencies RUN apt-get update && \ apt-get install -y \ g++ \ make \ cmake \ unzip \ libcurl4-openssl-dev # Copy function code RUN mkdir -p ${FUNCTION_DIR} COPY . ${FUNCTION_DIR} WORKDIR ${FUNCTION_DIR} # Install Node.js dependencies RUN npm install # Install the runtime interface client RUN npm install aws-lambda-ric # Grab a fresh slim copy of the image to reduce the final size FROMnode:20-bookworm-slim# Required for Node runtimes which use npm@8.6.0+ because # by default npm writes logs under /home/.npm and Lambda fs is read-only ENV NPM_CONFIG_CACHE=/tmp/.npm # Include global arg in this stage of the build ARG FUNCTION_DIR # Set working directory to function root directory WORKDIR ${FUNCTION_DIR} # Copy in the built dependencies COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR} # Set runtime interface client as default command for the container runtime ENTRYPOINT ["/usr/local/bin/npx", "aws-lambda-ric"] # Pass the name of the function handler as an argument to the runtime CMD ["index.handler"] -
-
Erstellen Sie Ihr Docker-Image mit dem docker build
-Befehl. Das folgende Beispiel benennt das Bild in docker-imageund gibt ihm dentestTag. Um Ihr Image mit Lambda kompatibel zu machen, müssen Sie die Option --provenance=falseverwenden.docker buildx build --platform linux/amd64 --provenance=false -tdocker-image:test.Anmerkung
Der Befehl gibt die
--platform linux/amd64-Option an, um sicherzustellen, dass Ihr Container mit der Lambda-Ausführungsumgebung kompatibel ist, unabhängig von der Architektur des Entwicklungsrechners. Wenn Sie beabsichtigen, eine Lambda-Funktion mithilfe der ARM64-Befehlssatzarchitektur zu erstellen, müssen Sie den Befehl unbedingt so ändern, dass stattdessen die--platform linux/arm64-Option verwendet wird.
Verwenden Sie den Laufzeit-Schnittstellen-Emulator
Installieren des Laufzeitschnittstellen-Emulators auf Ihrem lokalen Computer
-
Führen Sie in Ihrem Projektverzeichnis den folgenden Befehl aus, um den Laufzeitschnittstellen-Emulator (x86-64-Architektur) von GitHub herunterzuladen und auf Ihrem lokalen Computer zu installieren.
-
Starten Sie Ihr Docker-Image mit dem docker run-Befehl. Beachten Sie Folgendes:
-
docker-imageist der Image-Name undtestist das Tag. -
/usr/local/bin/npx aws-lambda-ric index.handleristENTRYPOINTgefolgt vonCMDaus Ihrem Dockerfile.
Dieser Befehl führt das Image als Container aus und erstellt einen lokalen Endpunkt bei
localhost:9000/2015-03-31/functions/function/invocations.Anmerkung
Wenn Sie das Docker-Image für die ARM64-Befehlssatz-Architektur erstellt haben, müssen Sie die Option
--platform linux/stattarm64--platform linux/verwenden.amd64 -
-
Veröffentlichen Sie ein Ereignis auf dem lokalen Endpunkt.
-
Die Container-ID erhalten.
docker ps -
Verwenden Sie den Befehl docker kill
, um den Container zu anzuhalten. Ersetzen Sie in diesem Befehl 3766c4ab331cdurch die Container-ID aus dem vorherigen Schritt.docker kill3766c4ab331c
Um das Image in Amazon ECR hochzuladen und die Lambda-Funktion zu erstellen
-
Führen Sie den Befehl get-login-password
aus, um die Docker-CLI bei Ihrem Amazon-ECR-Registry zu authentifizieren. -
Stellen Sie den
--regionWert auf die AWS-Region ein, in der Sie das Amazon-ECR-Repository erstellen möchten. -
Ersetzen Sie
111122223333mit Ihrer AWS-Konto-ID.
aws ecr get-login-password --regionus-east-1| docker login --username AWS --password-stdin111122223333.dkr.ecr.us-east-1.amazonaws.com -
-
Erstellen Sie ein Repository in Amazon ECR mithilfe des Befehls create-repository
. aws ecr create-repository --repository-namehello-world--regionus-east-1--image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLEAnmerkung
Das Amazon ECR-Repository muss sich im selben AWS-Region wie die Lambda-Funktion befinden.
Wenn erfolgreich, sehen Sie eine Antwort wie diese:
{ "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" } } } -
Kopieren Sie das
repositoryUriaus der Ausgabe im vorherigen Schritt. -
Führen Sie den Befehl docker tag
aus, um Ihr lokales Image als neueste Version in Ihrem Amazon-ECR-Repository zu markieren. In diesem Befehl gilt Folgendes: -
docker-image:testist der Name und das TagIhres Docker-Images. Dies sind der Imagename und das Tag, die Sie im docker build-Befehl angegeben haben. -
Ersetzen Sie
<ECRrepositoryUri>durch denrepositoryUri, den Sie kopiert haben. Stellen Sie sicher, dass Sie:latestam Ende der URI angeben.
docker tag docker-image:test<ECRrepositoryUri>:latestBeispiel:
docker tagdocker-image:test111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest -
-
Führen Sie den Befehl docker push
aus, um Ihr lokales Image im Amazon-ECR-Repository bereitzustellen. Stellen Sie sicher, dass Sie :latestam Ende der Repository-URI angeben.docker push111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest -
Erstellen Sie eine Ausführungsrolle für die Funktion, wenn Sie noch keine haben. Sie benötigen den Amazon-Ressourcennamen (ARN) der Rolle im nächsten Schritt.
-
So erstellen Sie die Lambda-Funktion: Geben Sie für
ImageUridie Repository-URI von zuvor an. Stellen Sie sicher, dass Sie:latestam Ende der URI angeben.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-exAnmerkung
Sie können eine Funktion mit einem Bild in einem anderen AWS-Konto erstellen, sofern sich das Bild in derselben Region wie die Lambda-Funktion befindet. Weitere Informationen finden Sie unter Kontoübergreifende Berechtigungen von Amazon ECR.
-
Die Funktion aufrufen.
aws lambda invoke --function-namehello-worldresponse.jsonDas Ergebnis sollte ungefähr wie folgt aussehen:
{ "ExecutedVersion": "$LATEST", "StatusCode": 200 } -
Um die Ausgabe der Funktion zu sehen, überprüfen Sie die
response.json-Datei.
Um den Funktionscode zu aktualisieren, müssen Sie das Image erneut erstellen, das neue Image in das Amazon-ECR-Repository hochladen und dann den Befehl update-function-code
Lambda löst das Image-Tag in einen bestimmten Image-Digest auf. Das heißt, wenn Sie das Image-Tag, das zur Bereitstellung der Funktion verwendet wurde, auf ein neues Image in Amazon ECR verweisen, aktualisiert Lambda die Funktion nicht automatisch, um das neue Image zu verwenden.
Um das neue Image für dieselbe Lambda-Funktion bereitzustellen, müssen Sie den Befehl update-function-code--publish-Option eine neue Version der Funktion unter Verwendung des aktualisierten Container-Images.
aws lambda update-function-code \ --function-namehello-world\ --image-uri111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest\ --publish