Overcast is alpha — behaviour and APIs may change between releases. Pin your version and read the changelog before upgrading.

overcast

Behavioural differences from LocalStack

What changes once the container is running: editions and plans, egress, S3 addressing, SQS queue URLs, Lambda execution, persistence and request IDs.

The deliberate divergences behind Migrating from LocalStack, so you know what to expect once the container is up. Item-by-item status for every port, URL, hostname and client tool is in the compatibility matrix.

AreaOn LocalStackOn Overcast
EditionsOne image for every plan, an auth token to start it, most services on a paid planNo plans, no token. Every emulated service is in the one build
EgressA Docker network is never isolated, so a VPC function always reaches the internetThe same by default, and OVERCAST_VPC_EGRESS can withhold it or follow your route tables
S3 addressingVirtual-hosted style needs an s3. prefix on your endpointPath-style by default; both virtual-hosted forms work with no prefix
SQS queue URLsSQS_ENDPOINT_STRATEGY picks the hostThe URL is minted on the origin the caller reached
Lambda executionDocker, or a local executorDocker, on the official AWS base images
PersistenceEnabled when DATA_DIR is setauto infers it the same way
Request IDsOmitted from some error responsesx-amz-request-id (or x-amzn-requestid) on every response, errors included
SigV4 signaturesVerifiedAccepted, not verified, until OVERCAST_SIGV4_VALIDATE=true
IAM policiesEnforced in strict modeStored, never enforced, until OVERCAST_ENFORCE_IAM=true

Editions and plans

LocalStack restructured its editions on 23 March 2026: one image for every plan, an auth token required to start it, and a free “Hobby” plan for non-commercial use that leaves most services, and local state persistence, to the paid Base and Ultimate plans. Overcast has no plans, so a setup that leaned on a paid-plan service — ECS, RDS, Cognito, CloudFront and the others named in the matrix — migrates the same way as one using S3 and SQS, and persistence needs nothing beyond a mounted volume (see Storage and persistence).

A carried-over LOCALSTACK_AUTH_TOKEN is recognised and inert: startup logs it once by name, nothing is gated behind it, and it can stay or go. What has no equivalent here was never a plan question — snapshot save/load, SQS_ENDPOINT_STRATEGY and the /_aws/* inspection endpoints are each listed in the matrix with the alternative.

Egress

LocalStack never isolates a Docker network, so a Lambda in a VPC reaches the internet there whatever its subnets look like. Overcast’s default, OVERCAST_VPC_EGRESS=open, is the same — a migration needs nothing here. none withholds egress from everything Overcast starts and routed decides it per subnet from the route table; both are described in Egress modes and routed.

Two notes if you are moving from an Overcast between 0.0.1-alpha.37 and this release: egress on your machine may have been withheld and is not any more, and OVERCAST_CONTROL_PLANE_INTERNAL is deprecated in favour of the mode. If you set it to false to restore LocalStack’s behaviour, drop it — that is now the default.

S3: path-style by default, virtual-hosted supported

Overcast returns path-style URLs (http://localhost:4566/bucket/key). Both virtual-hosted forms work too — bucket.s3.<base> and the bare bucket.<base> — and neither needs an s3. prefix on your endpoint. What they do need is for the bucket subdomain to resolve: set OVERCAST_HOSTNAME=localhost.overcast.sh, and an existing localhost.localstack.cloud keeps working — see Hostnames that resolve for every caller.

To force path-style instead of configuring a hostname:

aws configure set s3.addressing_style path                                  # AWS CLI
# boto3: boto3.client('s3', config=Config(s3={'addressing_style': 'path'}))

Warning

CDK’s asset publisher always uses virtual-hosted style and ignores forcePathStyle, so on Windows it needs the hostname, not the setting — see CDK § S3 asset upload fails on Windows.

SQS: queue URLs follow the caller

There is no SQS_ENDPOINT_STRATEGY equivalent. Overcast mints each queue URL on the origin the caller reached it on, so a host CLI gets localhost:4566 and a Lambda container gets an address it can dial. This matters because AWS SDKs resolve the SQS endpoint from the QueueUrl and ignore AWS_ENDPOINT_URL when doing so — see SQS § Queue URLs and endpoint resolution. Queue URLs carried over from a LocalStack setup keep resolving on both sides of the container boundary, because localhost.localstack.cloud is remapped to Overcast inside the containers it starts. Drop SQS_ENDPOINT_STRATEGY.

Lambda: Docker-based execution

Functions run in containers built on the official AWS base images (public.ecr.aws/lambda/<runtime>), so the Docker socket has to be reachable — see LAMBDA_DOCKER_SOCKET and OVERCAST_NETWORK in the configuration reference. Without Docker, functions can still be created and managed; invocations degrade to a built-in Node.js runtime for simple handlers.

Persistence: auto-detected, like LocalStack’s DATA_DIR presence

LocalStack enables persistence when DATA_DIR is set. Overcast’s default, auto, infers it the same way — see Storage and persistence § The auto default. Set OVERCAST_STATE explicitly for a specific backend regardless of what is mounted.

A volume carried over at LocalStack’s own path is read where it is. Overcast keeps state in /data, but a compose file migrated line by line still mounts /var/lib/localstack — so when that is the only volume mounted, it becomes the state directory and a startup line says so. Mount /data, or set OVERCAST_DATA_DIR, to choose otherwise; either wins.

volumes:
  - "./volume:/var/lib/localstack" # works unchanged
  - "/var/run/docker.sock:/var/run/docker.sock"

Warning

Not true of the overcast-slim image or the overcastd binaries. Both are built without SQLite, so auto there always resolves to memory — a mounted volume gives you no persistence at all, and nothing announces it beyond the startup log. Replacing a LocalStack container that had DATA_DIR set? Use the full ghcr.io/overcast-sh/overcast image, or add OVERCAST_STATE=wal. See Builds without SQLite.