# Deploy a Bun application on AWS Lambda

[AWS Lambda](https://aws.amazon.com/lambda/) is a serverless compute service that lets you run code without provisioning or managing servers.

This guide deploys a Bun HTTP server to AWS Lambda using a `Dockerfile`.

<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 and added to your `PATH`

</Note>

---

<Steps>
	<Step title="Create a new Dockerfile">
		Create a new `Dockerfile` in the root of your project. This file contains the instructions to initialize the container, copy your local project files into it, install dependencies, and start the application.

    	```docker Dockerfile icon="docker"
    	# Use the official AWS Lambda adapter image to handle the Lambda runtime
    	FROM public.ecr.aws/awsguru/aws-lambda-adapter:0.9.0 AS aws-lambda-adapter

    	# Use the official Bun image to run the application
    	FROM oven/bun:debian AS bun_latest

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

    	# Set the port to 8080. This is required for the AWS Lambda adapter.
    	ENV PORT=8080

    	# Set the work directory to `/var/task`. This is the default work directory for Lambda.
    	WORKDIR "/var/task"

    	# Copy the package.json and bun.lock into the container
    	COPY package.json bun.lock ./

    	# Install the dependencies
    	RUN bun install --production --frozen-lockfile

    	# Copy the rest of the application into the container
    	COPY . /var/task

    	# Run the application.
    	CMD ["bun", "index.ts"]
    	```

    	<Note>
    		Make sure that the start command corresponds to your application's entry point. This can also be `CMD ["bun", "run", "start"]` if you have a start script in your `package.json`.

    		If your app doesn't have dependencies, you can omit the `RUN bun install --production --frozen-lockfile` line.
    	</Note>

    	Create a new `.dockerignore` file in the root of your project. It lists the files and directories to _exclude_ from the container image, such as `node_modules`, which keeps builds faster and smaller:

    	```docker .dockerignore icon="Docker"
    	node_modules
    	Dockerfile*
    	.dockerignore
    	.git
    	.gitignore
    	README.md
    	LICENSE
    	.vscode
    	.env
    	# Any other files or directories you want to exclude
    	```
    </Step>
    <Step title="Build the Docker image">
    	Make sure you're in the directory containing your `Dockerfile`, then build the Docker image. This example names the image `bun-lambda-demo` and tags it as `latest`.

    	```bash terminal icon="terminal"
    	# cd /path/to/your/app
    	docker build --provenance=false --platform linux/amd64 -t bun-lambda-demo:latest .
    	```
    </Step>
    <Step title="Create an ECR repository">
    	Before pushing the image, create an [ECR repository](https://aws.amazon.com/ecr/) to push it to.

    	The following command:
    	- Creates an ECR repository named `bun-lambda-demo` in the `us-east-1` region
    	- Exports the repository URI as an environment variable. This is optional, but makes the next steps easier.

    	```bash terminal icon="terminal"
    	export ECR_URI=$(aws ecr create-repository --repository-name bun-lambda-demo --region us-east-1 --query 'repository.repositoryUri' --output text)
    	echo $ECR_URI
    	```
    	```txt
    	[id].dkr.ecr.us-east-1.amazonaws.com/bun-lambda-demo
    	```

    	<Note>
    		If you're using IAM Identity Center (SSO) or have configured AWS CLI with profiles, add the `--profile` flag to your AWS CLI commands.

    		For example, if your profile is named `my-sso-app`, use `--profile my-sso-app`. Run `aws configure list-profiles` to see your available profiles.

    		```bash terminal icon="terminal"
    		export ECR_URI=$(aws ecr create-repository --repository-name bun-lambda-demo --region us-east-1 --profile my-sso-app --query 'repository.repositoryUri' --output text)
    		echo $ECR_URI
    		```
    	</Note>

    </Step>
    <Step title="Authenticate with the ECR repository">
    	Log in to the ECR repository:

    	```bash terminal icon="terminal"
    	aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin $ECR_URI
    	```
    	```txt
    	Login Succeeded
    	```

    	<Note>
    		If using a profile, use the `--profile` flag:

    		```bash terminal icon="terminal"
    		aws ecr get-login-password --region us-east-1 --profile my-sso-app | docker login --username AWS --password-stdin $ECR_URI
    		```

    	</Note>

    </Step>
    <Step title="Tag and push the docker image to the ECR repository">
    	Make sure you're in the directory containing your `Dockerfile`, then tag the Docker image with the ECR repository URI.

    	```bash terminal icon="terminal"
    	docker tag bun-lambda-demo:latest ${ECR_URI}:latest
    	```

    	Then, push the image to the ECR repository.

    	```bash terminal icon="terminal"
    	docker push ${ECR_URI}:latest
    	```
    </Step>
    <Step title="Create an AWS Lambda function">
    	Go to **AWS Console** > **Lambda** > [**Create Function**](https://us-east-1.console.aws.amazon.com/lambda/home?region=us-east-1#/create/function?intent=authorFromImage) > Select **Container image**

    	<Warning>Make sure you've selected the right region. This URL defaults to `us-east-1`.</Warning>

    	<Frame>
    	![Create Function](/images/guides/lambda1.png)
    	</Frame>

    	Give the function a name, like `my-bun-function`.
    </Step>
    <Step title="Select the container image">
    	Go to the **Container image URI** section and click **Browse images**. Select the image you pushed to the ECR repository.

    	<Frame>
    	![Select Container Repository](/images/guides/lambda2.png)
    	</Frame>

    	Then, select the `latest` image and click **Select image**.

    	<Frame>
    	![Select Container Image](/images/guides/lambda3.png)
    	</Frame>
    </Step>
    <Step title="Configure the function">
    	To get a public URL for the function, go to **Additional configurations** > **Networking** > **Function URL**.

    	Set this to **Enable**, with Auth Type **NONE**.

    	<Frame>
    		![Set the Function URL](/images/guides/lambda4.png)
    	</Frame>
    </Step>
    <Step title="Create the function">
    	Click **Create function** at the bottom of the page.

    	<Frame>
    		![Create Function](/images/guides/lambda6.png)
    	</Frame>

    </Step>
    <Step title="Get the function URL">
    	Once the function is created, you're redirected to its page. The function URL is in the **"Function URL"** section.

    	<Frame>
    		![Function URL](/images/guides/lambda5.png)
    	</Frame>
    </Step>
    <Step title="Test the function">
    	Your app is now live. To test the function, either go to the **Test** tab or call the function URL directly.

    	```bash terminal icon="terminal"
    	curl -X GET https://[your-function-id].lambda-url.us-east-1.on.aws/
    	```
    	```txt
    	Hello from Bun on Lambda!
    	```
    </Step>

</Steps>
