Docker
Run LocalEmu as a Docker container for isolated, reproducible environments. Ideal for CI/CD pipelines and team setups.
docker run
The simplest way to start LocalEmu in Docker. Mount the Docker socket so Lambda, ECS, and EC2 can spawn real containers:
$ docker run -d \
--name localemu \
-p 4566:4566 \
-p 4510-4559:4510-4559 \
-v /var/run/docker.sock:/var/run/docker.sock \
--group-add docker \
localemu/localemu:latest $ docker run -d \
--name localemu \
-p 4566:4566 \
-p 4510-4559:4510-4559 \
-v /var/run/docker.sock:/var/run/docker.sock \
--user root \
localemu/localemu:latest Why --user root on macOS?
Lambda, ECS, and EC2 services spawn real Docker containers for function execution.
On Docker Desktop for Mac the socket is owned by root
inside the container regardless of host GID, so the non-root
localemu user cannot access it. On Linux,
adding the docker group
(--group-add docker) is sufficient.
Once the container is running, use the standard AWS CLI from your host:
Using the AWS CLI with Docker
# Set once, then use the standard aws CLI, no flags needed
$ export AWS_ENDPOINT_URL=http://localhost:4566
$ export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
$ export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
$ export AWS_DEFAULT_REGION=us-east-1
$ aws s3 ls
$ aws dynamodb list-tables
$ aws lambda list-functions # Add to ~/.bashrc or ~/.zshrc
alias awsemu='aws --endpoint-url=http://localhost:4566 --region us-east-1'
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
$ awsemu s3 ls
$ awsemu sqs list-queues $ docker exec localemu bash -c \
'. /opt/code/localemu/.venv/bin/activate && awsemu s3 ls' Tip: Option A with
AWS_ENDPOINT_URL is the cleanest: boto3
and the AWS CLI both read it automatically since CLI v2. Your code works identically on
LocalEmu and real AWS by just unsetting the env var.
Persistence
By default, LocalEmu state is ephemeral: everything is lost when the container stops. To keep your resources across restarts, enable persistence and mount a volume:
$ docker run -d \
--name localemu \
-p 4566:4566 \
-v localemu-data:/var/lib/localemu \
-e PERSISTENCE=1 \
--user root \
localemu/localemu:latest State is saved on shutdown and restored on startup. S3 buckets, DynamoDB tables, Lambda functions, SQS queues, Secrets Manager secrets: everything survives.
Save Strategies
Control when state is saved via the SNAPSHOT_SAVE_STRATEGY environment variable:
| Strategy | Behavior |
|---|---|
ON_SHUTDOWN | Saves when LocalEmu stops (default) |
SCHEDULED | Saves every 15 seconds (configurable via SNAPSHOT_FLUSH_INTERVAL) |
MANUAL | Save and load only via REST API (see below) |
REST API for Manual Control
Three endpoints let you manage state snapshots programmatically:
| Endpoint | Description |
|---|---|
POST /_localemu/state/save | Save current state to disk |
POST /_localemu/state/load | Load state from disk |
GET /_localemu/state/status | Check persistence status |
# Save state manually
$ curl -X POST http://localhost:4566/_localemu/state/save
{"status": "saved"}
# Check persistence status
$ curl http://localhost:4566/_localemu/state/status
{"persistence": "enabled", "strategy": "ON_SHUTDOWN"} Tip: For CI/CD pipelines,
use SNAPSHOT_SAVE_STRATEGY=MANUAL and call the save/load
endpoints explicitly. This gives you full control over when state snapshots are taken.
$ curl http://localhost:4566/_localemu/health
{"status": "running"}
$ awsemu s3 mb s3://test-bucket
make_bucket: test-bucket docker-compose.yml
For projects that need LocalEmu alongside other services (databases, app servers), use Docker Compose:
version: "3.8"
services:
localemu:
image: localemu/localemu:latest
container_name: localemu
ports:
- "4566:4566"
- "4510-4559:4510-4559"
environment:
- PERSISTENCE=1
- DEBUG=0
- GATEWAY_LISTEN=0.0.0.0:4566
- LAMBDA_DOCKER_NETWORK=my-network
volumes:
- localemu-data:/var/lib/localemu
- "/var/run/docker.sock:/var/run/docker.sock"
networks:
- my-network
app:
build: .
depends_on:
- localemu
environment:
- AWS_ENDPOINT_URL=http://localemu:4566
- AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
- AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
- AWS_DEFAULT_REGION=us-east-1
networks:
- my-network
volumes:
localemu-data:
networks:
my-network:
driver: bridge $ docker compose up -d
Creating localemu ... done
Creating app ... done Port Mappings
| Port | Purpose | Required |
|---|---|---|
4566 | Main gateway for all services | Yes |
4510-4559 | External service ports (used by some services like OpenSearch, RDS) | Optional |
Most services work through port 4566 alone. The extended range is only needed if you use services that expose dedicated ports, like OpenSearch or RDS.
Volume Mounts
| Volume | Purpose | Required |
|---|---|---|
/var/lib/localemu | Persistent data storage. Mount this to keep data across container restarts when PERSISTENCE=1. | Optional |
/var/run/docker.sock | Docker socket. Required for Lambda to spawn function containers. | For Lambda |
/etc/localemu/init | Initialization scripts. Shell scripts placed here run on startup. | Optional |
Initialization Scripts
Mount a directory of shell scripts to /etc/localemu/init to automatically create resources on startup:
#!/bin/bash
awsemu s3 mb s3://app-uploads
awsemu sqs create-queue --queue-name tasks
awsemu dynamodb create-table \
--table-name Users \
--key-schema AttributeName=userId,KeyType=HASH \
--attribute-definitions AttributeName=userId,AttributeType=S \
--billing-mode PAY_PER_REQUEST volumes:
- "./init-scripts:/etc/localemu/init"
- "/var/run/docker.sock:/var/run/docker.sock" Environment Variables
Pass environment variables to configure LocalEmu behavior inside the container:
$ docker run -d \
--name localemu \
-p 4566:4566 \
-e PERSISTENCE=1 \
-e DEBUG=1 \
-e SERVICES=s3,sqs,dynamodb,lambda \
-e LAMBDA_DOCKER_NETWORK=my-network \
-v localemu-data:/var/lib/localemu \
-v /var/run/docker.sock:/var/run/docker.sock \
localemu/localemu:latest See the Configuration page for the full list of environment variables.