A Docker‑backed AWS Lambda clone that runs locally. Lambda@Home provides Lambda‑compatible APIs, a web console, and executes functions in Docker containers with a Lambda‑like lifecycle.
Repository: https://github.com/fearlessfara/lambda-at-home
One-line install for all platforms:
curl -fsSL https://raw.githubusercontent.com/fearlessfara/lambda-at-home/main/install-lambda-at-home.sh | bashThis will:
- ✅ Download the latest binary for your platform (Linux x86_64, Linux ARM64, macOS Intel, macOS Apple Silicon)
- ✅ Create the necessary directory structure
- ✅ Set up configuration with sensible defaults
- ✅ Verify the binary with checksums
Start Lambda@Home:
cd lambda@home
./lambda-at-home-serverAccess the web console: http://localhost:9000
- Lambda‑compatible User API and in‑container Runtime API
- Docker‑based isolation for function execution
- Runtimes: Node.js 18/22, Python 3.11, Rust
- Warm pool + reuse:
WarmIdle → Active → WarmIdle - Idle management: soft stop and hard removal with watchdog
- Autoscaling: scales to queue depth; restarts stopped instances first
- Concurrency control: global + per‑function reserved concurrency
- API Gateway path proxy with route mappings (prefix + method)
- Web Console: create/update functions, test invoke, manage API routes and Secrets
- Secrets: store once, reference in env as
SECRET_REF:NAME(masked in UI) - Metrics: Prometheus endpoint; structured tracing logs
- Security: non‑root, read‑only rootfs, capability drop, tmpfs
Lambda@Home consists of several components:
- User API (port 9000): AWS Lambda-compatible REST API
- Runtime API (port 9001): In-container runtime interface (RIC)
- Control Plane: Function registry, scheduler, warm pool management
- Invoker: Docker container lifecycle management
- Packaging: ZIP processing and Docker image building
- Metrics: Prometheus metrics and structured logging
- Console: React app (Vite) for managing functions, API Gateway routes, and Secrets
- Docker installed and running
- Rust 1.75+ (with rustup) - only needed for development
- Make (optional, for convenience commands) - only needed for development
- Clone the repository
git clone https://github.com/fearlessfara/lambda-at-home.git
cd lambda-at-home- Build the project
make releaselambda-at-home-servermake run
# or
./target/release/lambda-at-home-serverThe server will start on:
- User API: http://127.0.0.1:9000/api
- Web Console: http://127.0.0.1:9000 (embedded in binary)
- Runtime API: http://127.0.0.1:9001
- Health: http://127.0.0.1:9000/api/healthz
- Metrics: http://127.0.0.1:9000/api/metrics
The web console is embedded in the binary and available at http://127.0.0.1:9000. No separate setup required!
For development, you can run the console separately:
cd console
npm install
npm run dev
# open http://localhost:3000Configure the API base URL via console/.env (defaults to /api in production builds):
VITE_API_URL=http://localhost:9000/api
Package a ZIP with your handler (Node example: index.js with exports.handler). Then:
Create function
ZIP_B64=$(base64 < test-function.zip | tr -d '\n')
curl -sS -X POST http://127.0.0.1:9000/2015-03-31/functions \
-H 'content-type: application/json' \
-d "{\n \"function_name\": \"echo\",\n \"runtime\": \"nodejs18.x\",\n \"handler\": \"index.handler\",\n \"code\": { \"zip_file\": \"$ZIP_B64\" }\n }"Invoke function
curl -sS -X POST http://127.0.0.1:9000/2015-03-31/functions/echo/invocations \
-H 'content-type: application/json' \
-d '{"ping":1}' | jqConfiguration is managed via service/configs/default.toml (or configs/default.toml). Missing or invalid files fall back to sensible defaults:
[server]
bind = "127.0.0.1"
port_user_api = 9000
port_runtime_api = 9001
max_request_body_size_mb = 50
[data]
dir = "data"
db_url = "sqlite://data/lhome.db"
[docker]
host = ""
[defaults]
memory_mb = 512
timeout_ms = 3000
tmp_mb = 512
[idle]
soft_ms = 45000 # stop container
hard_ms = 300000 # rm container
[limits]
max_global_concurrency = 256- Runtimes:
nodejs18.x,nodejs22.x - Handler format:
filename.export - Example:
index.handler
- Runtime:
python3.11 - Handler format:
filename.function - Example:
lambda_function.handler
- Runtime:
rust - Handler format:
binary_name - Example:
lambda
POST /2015-03-31/functions- Create functionGET /2015-03-31/functions/{name}- Get functionDELETE /2015-03-31/functions/{name}- Delete functionPUT /2015-03-31/functions/{name}/code- Update function codePUT /2015-03-31/functions/{name}/configuration- Update function configPOST /2015-03-31/functions/{name}/versions- Publish versionGET /2015-03-31/functions- List functionsPOST /2015-03-31/functions/{name}/invocations- Invoke functionPUT /2015-03-31/functions/{name}/concurrency- Set reserved concurrencyGET /2015-03-31/functions/{name}/concurrency- Get reserved concurrencyDELETE /2015-03-31/functions/{name}/concurrency- Clear reserved concurrencyGET /api/healthz- Health checkGET /api/metrics- Prometheus metrics
Any unmatched path is treated as an API Gateway-style invoke:
- If a configured route mapping matches (longest prefix, optional method) → invokes mapped function
- Else the first URL segment is treated as a function name (if it exists)
Function results are mapped back to HTTP as follows:
- If payload is an object with
statusCode/body/headers→ use those - If payload is an object with
bodyonly → return body with status 200 - If payload is a string → return text body
- Otherwise → return JSON payload (status 200)
Admin endpoints for routes:
GET /api/admin/api-gateway/routes– list routesPOST /api/admin/api-gateway/routes– create route{ path, method?, function_name }DELETE /api/admin/api-gateway/routes/:id– delete route
GET /2018-06-01/runtime/invocation/next- Get next invocationPOST /2018-06-01/runtime/invocation/{requestId}/response- Post responsePOST /2018-06-01/runtime/invocation/{requestId}/error- Post errorPOST /2018-06-01/runtime/init/error- Post init error
- Non-root execution: Containers run as user 1000:1000
- Read-only rootfs: Container filesystem is read-only
- Capability dropping: All capabilities are dropped
- No new privileges: Containers cannot gain new privileges
- Resource limits: Memory, CPU, and process limits enforced
- Tmpfs for /tmp: Temporary directory with size limits
- Host-gateway mapping only: Containers use default Docker networking with
host.docker.internalfor Runtime API access
lambda@home/
├── service/
│ ├── src/bin/lambda-at-home-server.rs # Server entrypoint
│ ├── crates/
│ │ ├── api/ # User API (AWS Lambda compatible)
│ │ ├── runtime_api/ # Runtime API (for containers)
│ │ ├── control/ # Control plane (registry, scheduler, warm pool)
│ │ ├── invoker/ # Docker container lifecycle
│ │ ├── packaging/ # ZIP processing and image build/cache
│ │ ├── models/ # Shared data models
│ │ ├── metrics/ # Prometheus + tracing
│ │ └── cli/ # CLI utilities
│ ├── configs/ # Default config (e.g., default.toml)
│ └── runtimes/ # Runtime bootstraps (nodejs18/22, python311, rust)
├── console/ # Web console (Vite + React)
├── e2e/ # End-to-end tests (Jest/Node)
├── examples/ # Example functions
└── Makefile # Common dev/test targets
See TESTING.md for details.
# Format code
make fmt
# Run clippy
make clippyPrometheus metrics are available at /metrics:
lambda_invocations_total- Total invocationslambda_errors_total- Total errorslambda_throttles_total- Total throttleslambda_cold_starts_total- Total cold startslambda_duration_ms- Function execution durationlambda_init_duration_ms- Function initialization duration
Structured JSON logs with fields:
ts- Timestamplevel- Log levelmessage- Log messagefunction- Function nameversion- Function versionreq_id- Request IDcontainer_id- Container IDduration_ms- Execution durationbilled_ms- Billed durationmem_peak_mb- Peak memory usage
- Docker not running: Ensure Docker is installed and running
- Port conflicts: Check if ports 9000/9001 are available
- Permission issues: Ensure Docker daemon is accessible
- Build failures: Check Rust toolchain and dependencies
Run with debug logging:
RUST_LOG=debug cargo run --bin lambda-at-home-serverCheck container logs for function execution issues:
docker logs <container_id>- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Run
make testandmake clippy - Submit a pull request
MIT License - see LICENSE file for details.
Tagged builds (vX.Y.Z) trigger the release workflow and publish platform binaries with the web console embedded. Download from GitHub Releases.
Local release build:
make release
./target/release/lambda-at-home-server- Web Console: functions, testing, API Gateway route management, Secrets
- API Gateway route mappings (prefix + method)
- Per-function reserved concurrency
- Secrets store with
SECRET_REF:NAMEenv resolution
-
Code update flow and versions/aliases UI
-
Layers support and more runtimes
-
Provisioned concurrency & prewarm controls
-
VPC networking support
-
Provisioned concurrency
-
Layer support
-
More runtime languages
-
WebSocket support
-
Event source mappings
-
Dead letter queues
-
X-Ray tracing integration