amplify-backend icon indicating copy to clipboard operation
amplify-backend copied to clipboard

Run lambda function inside docker

Open natcohen opened this issue 4 months ago • 1 comments

Environment information

System:
  OS: macOS 15.5
  CPU: (8) arm64 Apple M1
  Memory: 244.39 MB / 16.00 GB
  Shell: /bin/zsh
Binaries:
  Node: 24.2.0 - ~/.nvm/versions/node/v24.2.0/bin/node
  Yarn: undefined - undefined
  npm: 11.4.2 - ~/Library/CloudStorage/Dropbox/WebApps/provider-portal/node_modules/.bin/npm
  pnpm: 10.12.1 - /usr/local/bin/pnpm
NPM Packages:
  @aws-amplify/auth-construct: 1.8.1
  @aws-amplify/backend: 1.16.1
  @aws-amplify/backend-ai: Not Found
  @aws-amplify/backend-auth: 1.7.1
  @aws-amplify/backend-cli: 1.8.0
  @aws-amplify/backend-data: 1.6.1
  @aws-amplify/backend-deployer: 2.1.3
  @aws-amplify/backend-function: 1.14.1
  @aws-amplify/backend-output-schemas: 1.7.0
  @aws-amplify/backend-output-storage: 1.3.1
  @aws-amplify/backend-secret: 1.4.0
  @aws-amplify/backend-storage: 1.4.1
  @aws-amplify/cli-core: 2.2.1
  @aws-amplify/client-config: 1.8.0
  @aws-amplify/data-construct: 1.16.3
  @aws-amplify/data-schema: 1.21.1
  @aws-amplify/deployed-backend-client: 1.8.0
  @aws-amplify/form-generator: 1.2.1
  @aws-amplify/model-generator: 1.2.0
  @aws-amplify/platform-core: 1.10.0
  @aws-amplify/plugin-types: 1.11.0
  @aws-amplify/sandbox: 2.1.2
  @aws-amplify/schema-generator: 1.4.0
  @aws-cdk/toolkit-lib: 1.1.1
  aws-amplify: 6.15.4
  aws-cdk-lib: 2.208.0
  typescript: 5.8.3
No AWS environment variables
No CDK environment variables

Describe the bug

I would like to run my handler function inside a docker to take advantage of libreoffice and convert a docx file to PDF. I have the following resource.ts for my lambda function:

import * as path from "node:path";
import { fileURLToPath } from "node:url";
import { defineFunction } from "@aws-amplify/backend";
import { Duration } from "aws-cdk-lib";
import { Code, Function, Runtime } from "aws-cdk-lib/aws-lambda";

// Get the directory of the current file, which is where the Dockerfile should be.
const functionDir = path.dirname(fileURLToPath(import.meta.url));

export const docxToPdf = defineFunction(
    (scope) =>
        new Function(scope, "docx-to-pdf", {
            // This handler value is a formality for FROM_IMAGE runtime.
            // The actual entry point is the CMD in your Dockerfile.
            handler: "index.handler",

            // Specify that the runtime is a custom Docker image.
            runtime: Runtime.FROM_IMAGE,

            // Set a longer timeout and increase memory, as LibreOffice can be resource-intensive.
            timeout: Duration.seconds(45),
            memorySize: 1024, // You may need to increase this to 2048 or more.

            // Tell CDK to build the Docker image from the Dockerfile in this directory
            // and use it as the function's code and runtime.
            code: Code.fromDockerBuild(functionDir, {
                platform: 'linux/amd64',
            }),
        })
);

and a Dockerfile:

FROM public.ecr.aws/x4k0r1b8/lambda-libreoffice-base:25.2-node22-x86_64

# Set the working directory to what CDK expects for asset staging
WORKDIR /asset

# Copy only the necessary code and package files
COPY handler.ts ./
COPY package.json ./

# Install dependencies and build the handler
RUN npm install
RUN npm run build

# Set the command for Lambda
CMD [ "index.handler" ]

but when building with npx ampx sandbox, I get the following error:

[+] Building 1.7s (12/12) FINISHED                                                                                                                                            docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                                                                          0.0s
 => => transferring dockerfile: 491B                                                                                                                                                          0.0s
 => [internal] load metadata for public.ecr.aws/x4k0r1b8/lambda-libreoffice-base:25.2-node22-x86_64                                                                                           1.6s
 => [auth] aws:: x4k0r1b8/lambda-libreoffice-base:pull token for public.ecr.aws                                                                                                               0.0s
 => [internal] load .dockerignore                                                                                                                                                             0.0s
 => => transferring context: 2B                                                                                                                                                               0.0s
 => [1/6] FROM public.ecr.aws/x4k0r1b8/lambda-libreoffice-base:25.2-node22-x86_64@sha256:1bbccb409c5c319ffe64ac411e70a2efa72a1b23d16aec2a0d35a2519a5bfe01                                     0.0s
 => => resolve public.ecr.aws/x4k0r1b8/lambda-libreoffice-base:25.2-node22-x86_64@sha256:1bbccb409c5c319ffe64ac411e70a2efa72a1b23d16aec2a0d35a2519a5bfe01                                     0.0s
 => [internal] load build context                                                                                                                                                             0.0s
 => => transferring context: 213B                                                                                                                                                             0.0s
 => CACHED [2/6] WORKDIR /asset                                                                                                                                                               0.0s
 => CACHED [3/6] COPY handler.ts ./                                                                                                                                                           0.0s
 => CACHED [4/6] COPY package.json ./                                                                                                                                                         0.0s
 => CACHED [5/6] RUN npm install                                                                                                                                                              0.0s
 => CACHED [6/6] RUN npm run build                                                                                                                                                            0.0s
 => exporting to image                                                                                                                                                                        0.0s
 => => exporting layers                                                                                                                                                                       0.0s
 => => writing image sha256:e9dab3526fb08ef28d071f66931a13fd317559f697a18c8d044be59fbcc8ea43                                                                                                  0.0s
 => => naming to docker.io/library/cdk-bd087f1b3effa5f6671e654977afff6e51e2656bb2726356543327d169007ab6                                                                                       0.0s

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/x35i8ltc9l46u7wa4tiamuod3

What's next:
    View a summary of image vulnerabilities and recommendations → docker scout quickview 
Successfully copied 9.78MB to /private/var/folders/xp/3hdr9q512vbdv0hmdf7wsm5w0000gn/T/cdk-docker-cp-mULUba
3472cc423165dc4db62e650029272caf61b849b9b39cadade40bac5cdfb92ca3
3:16:27 PM ✔ Backend synthesized in 8.98 seconds
3:16:33 PM ✔ Type checks completed in 6.07 seconds
3:16:33 PM [ERROR] [BackendBuildError] Unable to deploy due to CDK Assembly Error
  ∟ Caused by: [AssemblyError] Assembly builder failed
    ∟ Caused by: [CustomFunctionProviderError] Failed to instantiate custom function provider
      ∟ Caused by: [ValidationError] runtime must be `Runtime.FROM_IMAGE` when using image asset for Lambda function
    Resolution: Check the definition of your custom function provided in `defineFunction` and refer to the logs for more information. See https://docs.amplify.aws/react/build-a-backend/functions/custom-functions for more details.
Resolution: Check the Caused by error and fix any issues in your backend code

What am I missing? my runtime is set to Runtime.FROM_IMAGE why is it complaining about that?

Reproduction steps

Write a dummy handler, a Dockerfile like mine and a resource.ts like the one mentioned above. Run in the sandbox.

natcohen avatar Jul 30 '25 14:07 natcohen

I don't think we can help you troubleshoot any specific image issues you might have. But, I'd suggest starting from a basic, known-working state and iteratively working towards the final state you need.

Here's an example that shows how to deploy a lambda with a specified image: https://github.com/svidgen/amplify-docker-lambda-testing/tree/as-define-function

I'd suggest pulling this simple example, deploying via sandbox, deploying via hosting/console, and then iterating towards what you need in small steps.

I'll leave this issue open for awhile in case you have questions about the basic setup.

svidgen avatar Aug 15 '25 16:08 svidgen