HTTP server runs on AWS Lambda

MORIYA Hiroyuki
3 min readFeb 19, 2023


With aws-lambda-adapter, you can easily run an HTTP server on a container image on AWS Lambda.

# Dockerfile

+ COPY /lambda-adapter /opt/extensions/lambda-adapter


I read a Japanese article about how to convert a web app to serverless.

I‘m interested in Rust, I tried to run an HTTP server using Rust web framework on AWS Lambda.

Example repository

HTTP server example (Rust — axum)

I implemented a HTTP Server by Rust and axum. This code is mostly sample code from axum repository.

use axum::{
routing::{get, post},
Json, Router,
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;

async fn main() {
// initialize tracing
// build our application with a route
let app = Router::new()
// `GET /` goes to `root`
.route("/", get(root))
// `POST /users` goes to `create_user`
.route("/users", post(create_user));
// run our app with hyper
// `axum::Server` is a re-export of `hyper::Server`
let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
tracing::debug!("listening on {}", addr);

// basic handler that responds with a static string
async fn root() -> &'static str {
"Hello, World!"

async fn create_user(
// this argument tells axum to parse the request body
// as JSON into a `CreateUser` type
Json(payload): Json<CreateUser>,
) -> (StatusCode, Json<User>) {
// insert your application logic here
let user = User {
id: 1337,
username: payload.username,
// this will be converted into a JSON response
// with a status code of `201 Created`
(StatusCode::CREATED, Json(user))

// the input to our `create_user` handler
struct CreateUser {
username: String,

// the output to our `create_user` handler
struct User {
id: u64,
username: String,

Build container image

Prepare a Dockerfile

This Dockerfile is normal for a web application.

# Dockerfile
FROM rust:1-slim-buster as builder
COPY ./Cargo.toml /app/Cargo.toml
COPY ./Cargo.lock /app/Cargo.lock
COPY ./src /app/src
RUN cargo build --release

FROM debian:buster-slim
COPY --from=builder "/app/target/release/example-rust-server-on-lambda" "/app/example-rust-server-on-lambda"
ENTRYPOINT ["/app/example-rust-server-on-lambda"]

Add to copy “aws-lambda-adapter” step

Add a step to the Dockerfile to copy aws-lambda-adapter. Just added this step, and the container image will be able to run on AWS Lambda.

FROM debian:buster-slim
+ COPY /lambda-adapter /opt/extensions/lambda-adapter
COPY --from=builder "/app/target/release/example-rust-server-on-lambda" "/app/example-rust-server-on-lambda"

Note: aws-lambda-adapter default port is “8080”. If your web application uses other port, you have to set environment variables.


Execute the following command to build the container image.

# Login to Amazon ECR Public
$ aws ecr-public get-login-password --region us-east-1 |
docker login --username AWS --password-stdin

# Build container image
$ export DOCKER_TAG="IMAGE_NAME:latest"
$ docker build --tag "${DOCKER_TAG}" .

Push to Amazon ECR

Execute the following command to push to the your ECR repository.

$ export DOCKER_TAG="IMAGE_NAME:latest"

$ aws ecr get-login-password --region ap-northeast-1 |
docker login --username AWS --password-stdin "${ECR_URI}"
$ docker tag "${DOCKER_TAG}" "${ECR_URI}"
$ docker push "${ECR_URI}"

Deploy to AWS Lambda with Pulumi

I deployed an axum HTTP server on AWS using Pulumi. The reason I used Pulumi is because I heard it is the modern IaC tool. However, you can deploy it any way you like, such as AWS console, Terraform, etc.

I wrote the following TypeScript code, but I’m a Pulumi beginner, so this code may not be the best way.

import * as aws from "@pulumi/aws";

const lambdaRole = new aws.iam.Role("example-rust-server-on-lambda-role", {
assumeRolePolicy: {
Version: "2012-10-17",
Statement: [{
Action: "sts:AssumeRole",
Principal: {
Service: "",
Effect: "Allow",
Sid: "",
new aws.iam.RolePolicyAttachment(
role: lambdaRole,
policyArn: aws.iam.ManagedPolicies.AWSLambdaExecute,

const lambdaFunction = new aws.lambda.Function(
packageType: "Image",
imageUri: process.env.ECR_URI,
role: lambdaRole.arn,

new aws.lambda.FunctionUrl("example-rust-server-on-lambda", {
authorizationType: "NONE",

Using Lambda function URLs

In this example, I use the Lambda function URLs. It provides an HTTP endpoint without using other services such as API Gateway.


Accessing HTTP endpoints via cURL and returns 200 Success.

# GET /
$ curl
Hello, World!

# POST /users
$ curl -XPOST \
-H 'Content-Type: application/json' \
-d '{"username":"mryhryki"}' \