Configuration

CLI flags and environment variables for fakecloud.

fakecloud is configured via CLI flags or environment variables. Flags take precedence when both are set.

FlagEnv VarDefaultDescription
--addrFAKECLOUD_ADDR0.0.0.0:4566Listen address and port
--regionFAKECLOUD_REGIONus-east-1AWS region to advertise
--account-idFAKECLOUD_ACCOUNT_ID123456789012AWS account ID
--log-levelFAKECLOUD_LOGinfoLog level (trace, debug, info, warn, error)
--storage-modeFAKECLOUD_STORAGE_MODEmemorymemory (default, all state in RAM) or persistent (mirror state to --data-path)
--data-pathFAKECLOUD_DATA_PATH—Directory to persist state to. Required when --storage-mode=persistent.
--s3-cache-sizeFAKECLOUD_S3_CACHE_SIZE268435456In-memory LRU cache for S3 object bodies in persistent mode. Default 256 MiB.
--dynamodb-import-pathFAKECLOUD_DYNAMODB_IMPORT_PATH—Bulk-load a single AWS-format DynamoDB S3 export as a new table at startup. Points at one export dir (AWSDynamoDB/<export-id>/, holding manifest-summary.json). Requires --dynamodb-import-describe-table; conflicts with --dynamodb-import-dir. Additive — writes straight into the store, no BatchWriteItem and no effect on the recorded ImportTable op. DYNAMODB_JSON format only; startup fails if a table of that name already exists. See DynamoDB.
--dynamodb-import-describe-tableFAKECLOUD_DYNAMODB_DESCRIBE_TABLE—Path to an aws dynamodb describe-table JSON dump supplying the table shape (key schema, attribute definitions, indexes, billing mode) for --dynamodb-import-path. Required together with --dynamodb-import-path; conflicts with --dynamodb-import-dir.
--dynamodb-import-dirFAKECLOUD_DYNAMODB_IMPORT_DIR—Bulk-load many AWS-format DynamoDB S3 exports as new tables at startup. Points at a root directory of per-table subdirectories, each self-contained with its own describe-table.json. Conflicts with --dynamodb-import-path/--dynamodb-import-describe-table. Same additive/DYNAMODB_JSON-only rules as --dynamodb-import-path; startup fails if any subdirectory is missing its describe-table.json. See DynamoDB.
--credentials-role-arnFAKECLOUD_CREDENTIALS_ROLE_ARNarn:aws:iam::<account>:role/fakecloudIAM role ARN the container/instance credential endpoint (GET /_fakecloud/credentials, consumed via AWS_CONTAINER_CREDENTIALS_FULL_URI) vends credentials for. Lets an app running under an instance/task role resolve the AWS SDK default credential chain locally with no code change. See Run an app unmodified.
--imds-instance-idFAKECLOUD_IMDS_INSTANCE_IDsynthetic i-…Instance ID the EC2 instance metadata service (IMDS, /latest/*) reports (meta-data/instance-id, the instance identity document). IMDS is consumed by pointing an app's SDK at AWS_EC2_METADATA_SERVICE_ENDPOINT=http://<host>:<port>/. See Run an app unmodified.
--imds-link-localFAKECLOUD_IMDS_LINK_LOCALfalseAlso bind the AWS link-local metadata addresses so apps that hardcode them resolve credentials unmodified: IMDS at 169.254.169.254:80 and ECS container credentials at 169.254.170.2:80/creds (set AWS_CONTAINER_CREDENTIALS_RELATIVE_URI=/creds), plus ECS task-role credentials at 169.254.170.2:80/v2/credentials/<task-id>. Requires running fakecloud as root (to bind port 80) with those addresses already assigned to the loopback interface; fakecloud binds them but never creates or deletes the alias, and logs the exact manual command if binding fails (the main server is unaffected). See advanced: apps that hardcode 169.254.169.254.
--dnsFAKECLOUD_DNSfalseRun a real DNS resolver that answers A/AAAA/CNAME/MX/TXT/NS/PTR/SPF/CAA from the Route 53 records created in fakecloud. Point a container's resolver at fakecloud (compose dns: / /etc/resolv.conf) and created records resolve to their local targets; names in no Route 53 zone forward upstream. See DNS resolver.
--dns-addrFAKECLOUD_DNS_ADDR0.0.0.0:53Address the DNS resolver binds (UDP + TCP). Binding port 53 needs root, so pass e.g. 127.0.0.1:15353 for an unprivileged run. Only used with --dns.
--dns-upstreamFAKECLOUD_DNS_UPSTREAMfirst non-loopback nameserver in /etc/resolv.conf, else 8.8.8.8:53Upstream resolver for names in no Route 53 zone, so a container can use fakecloud as its sole resolver and still reach the outside world. Only used with --dns.
--enforce-quotasFAKECLOUD_ENFORCE_QUOTASfalseEnforce every Service Quotas quota fakecloud can check, at its applied value. Nothing is enforced by default. See Service Quotas enforcement.
--enforce-quotaFAKECLOUD_ENFORCE_QUOTAnoneEnforce one quota, as SERVICE_CODE/QUOTA_CODE (e.g. vpc/L-0EA8095F). Repeatable; the env var takes a comma-separated list.
--ignore-quotaFAKECLOUD_IGNORE_QUOTAnoneNever enforce one quota, even with --enforce-quotas. Repeatable; the env var takes a comma-separated list. Both quota flags take only enforceable quotas (see the Service Quotas page); an unknown or non-enforceable code stops startup with an error.
--quota-requestsFAKECLOUD_QUOTA_REQUESTSautoHow Service Quotas increase requests are decided: auto (on submission) or manual (left PENDING until approved or denied through /_fakecloud/service-quotas/requests/{id}/...).
FAKECLOUD_CONTAINER_CLIauto-detectContainer CLI to use (docker or podman, or a path to either). Auto-detection tries docker, then podman. Podman is recognized by what the CLI is, not its name: a docker that is really podman (the podman-docker shim on Fedora/RHEL, or any wrapper) is detected via <cli> --version and driven as podman (host.containers.internal, --tls-verify=false for fakecloud's own registry).
FAKECLOUD_CONTAINER_BACKENDunset (docker)Global execution backend for all container-backed services (Lambda, ECS, RDS, ElastiCache, EC2). k8s runs them as native Kubernetes Pods. See Kubernetes backend.
FAKECLOUD_LAMBDA_BACKENDinherits globalPer-service override for Lambda (k8s or docker). Wins over FAKECLOUD_CONTAINER_BACKEND.
FAKECLOUD_ECS_BACKENDinherits globalPer-service override for ECS task execution (k8s or docker).
FAKECLOUD_ECS_CREDS_HELPER_IMAGEbuilt locally (Docker/Podman), public.ecr.aws/docker/library/alpine:3.20 (Kubernetes)Image that routes the ECS agent's 169.254.170.2 credentials address to fakecloud inside a task-role task's network. Needs sh, getent, awk, and nft or iptables. See ECS task role credentials.
FAKECLOUD_RDS_BACKENDinherits globalPer-service override for RDS DB instances (k8s or docker).
FAKECLOUD_ELASTICACHE_BACKENDinherits globalPer-service override for ElastiCache (k8s or docker).
FAKECLOUD_EC2_BACKENDinherits globalPer-service override for EC2 instances (k8s or docker).
FAKECLOUD_EC2_DEFAULT_IMAGEamazonlinux:2023Base container image EC2 instances boot from (any OS image with tail/sh).
FAKECLOUD_EC2_HELPER_IMAGEbuilt locally (Docker/Podman), public.ecr.aws/docker/library/alpine:3.20 (Kubernetes)Image of the sidecar that serves 169.254.169.254 (IMDS) inside each EC2 instance, and of the forwarders that let load balancers reach instance ports. Needs sh, getent, awk, nginx, socat, and nft or iptables (an Alpine image installs what is missing). See EC2 IMDS.
FAKECLOUD_ECR_REGISTRY_HOST127.0.0.1 (host.containers.internal for podman on macOS/Windows)Host the container engine pulls fakecloud-ECR images from for Lambda PackageType=Image functions and ECS tasks. See Pulling from fakecloud ECR.
FAKECLOUD_PERSIST_DB_VOLUMESon in persistent modeBack RDS (postgres/mysql/mariadb) data directories with a durable named volume so database contents survive a restart. In persistent mode the volume is scoped to the --data-path; in memory mode, to the fakecloud process (see Persistence). Defaults on under --storage-mode=persistent, off in memory mode. Set 1/0 to override.
FAKECLOUD_PERSIST_EC2_VOLUMESon in persistent modeBack each EC2 instance's data directory with a durable named volume so its contents survive a restart and stop/start. In persistent mode the volume is scoped to the --data-path; in memory mode, to the fakecloud process. Defaults on under --storage-mode=persistent, off in memory mode. Set 1/0 to override.
FAKECLOUD_EC2_INSTANCE_DATA_DIR/var/lib/fakecloud/ec2In-instance directory backed by the durable EC2 volume. Point it at wherever your instance workload writes long-lived state.
FAKECLOUD_LAMBDA_MAX_CONCURRENCY10Max warm instances kept per Lambda function. Each instance serves one invocation at a time (the runtime emulator can't handle concurrent events); the pool scales up to this cap under concurrent load, then queues. Raise for higher per-function concurrency.
FAKECLOUD_K8S_NAMESPACEdefaultNamespace fakecloud creates Pods in. Only honored on the K8s backend.
FAKECLOUD_K8S_SELF_URL—In-cluster URL of the fakecloud Service (e.g. http://fakecloud.fakecloud.svc.cluster.local:4566). Required for the K8s backend — Pods fetch artifacts from and call back to this URL.
FAKECLOUD_K8S_ECR_URLhost of _SELF_URLOverride the host:port the K8s backend rewrites AWS private-ECR URIs to. Defaults to the host of FAKECLOUD_K8S_SELF_URL.
FAKECLOUD_K8S_PULL_SECRETunsetName of a kubernetes.io/dockerconfigjson Secret used as imagePullSecrets for Pods pulling private images.
FAKECLOUD_K8S_NODE_SELECTORunsetkey=value,key=value node selector applied to every fakecloud Pod. Per-service override: FAKECLOUD_<SERVICE>_K8S_NODE_SELECTOR (e.g. FAKECLOUD_LAMBDA_K8S_NODE_SELECTOR). See Kubernetes backend.
FAKECLOUD_K8S_TOLERATIONSunsetJSON array of k8s Toleration objects applied to every fakecloud Pod. Per-service override: FAKECLOUD_<SERVICE>_K8S_TOLERATIONS.
FAKECLOUD_K8S_ANNOTATIONSunsetkey=value,key=value annotations added to every fakecloud Pod. Per-service override: FAKECLOUD_<SERVICE>_K8S_ANNOTATIONS.
FAKECLOUD_MAX_REQUEST_BODY_BYTES1073741824Max bytes a buffered request body can absorb before fakecloud returns 413. Default 1 GiB. Streaming routes (S3 PutObject / UploadPart, ECR OCI blob upload PATCH / PUT) bypass this cap entirely — they spool the raw HTTP body to disk instead of buffering it all in RAM. Raise this only when stress-testing buffered requests past 1 GiB.
FAKECLOUD_S3_EAGER_DELIVERYunset (off)Deliver S3 server access logs and inventory reports synchronously. Real S3 delivers both asynchronously (logs are best-effort with minutes-to-hours latency; inventory runs on a daily/weekly schedule), so by default fakecloud does not write these objects into the destination bucket, matching how a quick create/destroy never accumulates them. Set 1 to exercise the delivery paths, after which the destination bucket fills with log/report objects.
FAKECLOUD_CLOUDFRONT_DISABLE_DATAPLANEunset (on)Turn off the in-process CloudFront data plane. When set (1/true/yes), enabled distributions are not served on the main listener and report served: false via /_fakecloud/cloudfront/distributions; the control plane is unaffected. See CloudFront.
FAKECLOUD_EXTERNAL_URLunsetExternal base URL (e.g. http://fakecloud:4566) fakecloud renders into returned SQS QueueUrl values, for docker-compose/remote setups where clients reach fakecloud under a service name. When unset, the returned QueueUrl uses the request Host header (so a client that connects as http://fakecloud:4566 gets a routable URL), falling back to http://localhost:<port> when no Host is present. The stored queue identity stays host-independent; only the rendered URL reflects the caller.

Examples

# Bind to localhost only
fakecloud --addr 127.0.0.1:4566

# Verbose logging
fakecloud --log-level debug

# Different region and account
fakecloud --region eu-west-1 --account-id 999999999999

# Persistent storage
fakecloud --storage-mode persistent --data-path /var/lib/fakecloud

Environment-only configuration

FAKECLOUD_LOG=trace fakecloud
FAKECLOUD_REGION=eu-central-1 fakecloud

See also Persistence for details on persistent storage mode.

LocalStack and AWS URL compatibility

fakecloud decodes both LocalStack's *.localhost.localstack.cloud hostname convention and the real AWS *.amazonaws.com hostnames. Persisted URLs from either setup — queue URLs baked into dev scripts, presigned URLs in fixtures, webhook targets in response mocks — replay against fakecloud without rewriting. The following patterns are recognized on the Host header:

Host patternRouted as
<service>.<region>.localhost.localstack.cloud[:port]<service> in <region>
<bucket>.s3.<region>.localhost.localstack.cloud[:port]S3 virtual-hosted-style on <bucket>
<service>.<region>.amazonaws.com<service> in <region>
s3.<region>.amazonaws.comS3 path-style
<bucket>.s3.<region>.amazonaws.comS3 virtual-hosted-style on <bucket>
s3.amazonaws.comS3 path-style, legacy us-east-1 global
<bucket>.s3.amazonaws.comS3 virtual-hosted-style on <bucket>, us-east-1
s3-<region>.amazonaws.comS3 path-style, older dash-separated form
<bucket>.s3-<region>.amazonaws.comS3 virtual-hosted-style, older dash-separated

The DNS wildcard *.localhost.localstack.cloud resolves to 127.0.0.1, so LocalStack-shaped hostnames reach fakecloud unchanged; for AWS-shaped hostnames, point the client at fakecloud's endpoint (or add the names to /etc/hosts) and fakecloud parses the Host header to recover service, region, and (for S3) bucket. SigV4-signed requests still route by credential scope first — the hostname is a secondary signal that takes over when the request is unsigned, uses a non-standard Authorization header, or is being probed with curl.

# Unsigned SQS request — routed to SQS purely by Host header
curl -X POST \
     -H 'Host: sqs.us-east-1.amazonaws.com' \
     -d 'Action=ListQueues&Version=2012-11-05' \
     http://127.0.0.1:4566/

# Virtual-hosted-style S3 GetObject — bucket recovered from Host header
curl -H 'Host: my-bucket.s3.us-east-1.amazonaws.com' \
     http://127.0.0.1:4566/key

# Legacy global S3 endpoint — implicit us-east-1
curl -H 'Host: my-bucket.s3.amazonaws.com' http://127.0.0.1:4566/key

Bucket names with dots (e.g. a.b.c) are supported against every S3 suffix; fakecloud recognizes the .s3.<region> / .s3-<region> / .s3 trailer and treats everything before it as the bucket label.