> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/oven-sh/bun/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy to AWS Lambda

> Deploy a Bun HTTP server to AWS Lambda using a Docker container image and the AWS Lambda Web Adapter.

[AWS Lambda](https://aws.amazon.com/lambda/) is a serverless compute service that runs code without requiring you to provision or manage servers. Bun can run on AWS Lambda via a Docker container image using the [AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter).

<Note>
  Before continuing, make sure you have:

  * A Bun application ready for deployment
  * An [AWS account](https://aws.amazon.com/)
  * [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html) installed and configured
  * [Docker](https://docs.docker.com/get-started/get-docker/) installed
</Note>

<Steps>
  <Step title="Create a Dockerfile">
    The AWS Lambda Web Adapter bridges Lambda's event-based invocation model with a standard HTTP server. Create a `Dockerfile` in your project root:

    ```dockerfile Dockerfile theme={null}
    # Use the AWS Lambda adapter to handle the Lambda runtime protocol
    FROM public.ecr.aws/awsguru/aws-lambda-adapter:0.9.0 AS aws-lambda-adapter

    # Use the official Bun image (Debian-based for glibc compatibility)
    FROM oven/bun:debian AS bun_latest

    # Copy the Lambda adapter binary into the container
    COPY --from=aws-lambda-adapter /lambda-adapter /opt/extensions/lambda-adapter

    # Port 8080 is required by the AWS Lambda adapter
    ENV PORT=8080

    # /var/task is the default working directory for Lambda
    WORKDIR /var/task

    # Install dependencies
    COPY package.json bun.lock ./
    RUN bun install --production --frozen-lockfile

    # Copy application source
    COPY . /var/task

    # Start the app
    CMD ["bun", "index.ts"]
    ```

    <Note>
      Adjust the `CMD` to match your application's entry point. If you have a `start` script in `package.json`, you can use `CMD ["bun", "run", "start"]` instead.
    </Note>

    Also create a `.dockerignore` to keep the image small:

    ```text .dockerignore theme={null}
    node_modules
    Dockerfile*
    .dockerignore
    .git
    .gitignore
    README.md
    .env
    ```
  </Step>

  <Step title="Write a Bun HTTP server">
    Your server must listen on the port defined by the `PORT` environment variable (Lambda sets this to `8080`):

    ```typescript index.ts theme={null}
    const port = parseInt(process.env.PORT ?? "8080");

    Bun.serve({
      port,
      fetch(req) {
        const url = new URL(req.url);

        if (url.pathname === "/") {
          return new Response("Hello from Bun on Lambda!");
        }

        return new Response("Not Found", { status: 404 });
      },
    });

    console.log(`Listening on port ${port}`);
    ```
  </Step>

  <Step title="Build the Docker image">
    Build the image targeting the `linux/amd64` platform, which Lambda requires. The `--provenance=false` flag avoids a known ECR compatibility issue.

    ```bash theme={null}
    docker build --provenance=false --platform linux/amd64 -t bun-lambda-demo:latest .
    ```
  </Step>

  <Step title="Create an ECR repository">
    Create an Amazon Elastic Container Registry (ECR) repository to host the image, and export its URI:

    ```bash theme={null}
    export ECR_URI=$(aws ecr create-repository \
      --repository-name bun-lambda-demo \
      --region us-east-1 \
      --query 'repository.repositoryUri' \
      --output text)

    echo $ECR_URI
    ```

    ```text theme={null}
    123456789.dkr.ecr.us-east-1.amazonaws.com/bun-lambda-demo
    ```

    <Note>
      If you use IAM Identity Center (SSO), append `--profile <your-profile>` to every AWS CLI command.
    </Note>
  </Step>

  <Step title="Authenticate and push the image">
    Log in to ECR and push the image:

    ```bash theme={null}
    aws ecr get-login-password --region us-east-1 \
      | docker login --username AWS --password-stdin $ECR_URI

    docker tag bun-lambda-demo:latest ${ECR_URI}:latest
    docker push ${ECR_URI}:latest
    ```
  </Step>

  <Step title="Create an AWS Lambda function">
    In the AWS Console, navigate to **Lambda → Create function → Container image**.

    * Give the function a name (e.g., `my-bun-function`).
    * Under **Container image URI**, click **Browse images** and select the image you just pushed, choosing the `latest` tag.
  </Step>

  <Step title="Configure a public URL">
    To expose the function over HTTPS without an API Gateway:

    1. Open **Additional configurations → Networking → Function URL**.
    2. Set **Auth type** to **NONE** and click **Enable**.
    3. Click **Create function**.

    The function URL appears on the function's overview page.
  </Step>

  <Step title="Test the function">
    Call the function URL directly:

    ```bash theme={null}
    curl https://<your-function-id>.lambda-url.us-east-1.on.aws/
    ```

    ```text theme={null}
    Hello from Bun on Lambda!
    ```
  </Step>
</Steps>

## Environment variables

Set environment variables in the Lambda console under **Configuration → Environment variables**, or via the AWS CLI:

```bash theme={null}
aws lambda update-function-configuration \
  --function-name my-bun-function \
  --environment "Variables={DATABASE_URL=postgres://...,API_KEY=secret}"
```

Access them in your code with `process.env` or `Bun.env`:

```typescript theme={null}
const dbUrl = process.env.DATABASE_URL;
```

## IAM permissions

Lambda functions execute with the permissions of their associated IAM execution role. To grant your function access to other AWS services (e.g., S3, DynamoDB), attach the relevant managed policies or inline policies to the execution role in **IAM → Roles**.
