Docs / Docker

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:

Linux
$ 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
macOS (Docker Desktop)
$ 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

Option A: AWS_ENDPOINT_URL env var (recommended)
# 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
Option B: host-side awsemu alias
# 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
Option C: awsemu inside the container
$ 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 with persistence
$ 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
Example
# 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.

Verify
$ 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:

docker-compose.yml
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
Terminal
$ 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:

init-resources.sh
#!/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
docker-compose.yml (excerpt)
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 with env vars
$ 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.