application.yml Reference
Source builds only
This page is for users who build Floci from source or mount a custom application.yml into the container. If you run the published Docker image, you don't need this file — all settings are configured through FLOCI_* environment variables. See the Environment Variables Reference for the complete list.
All settings can be provided as YAML (in src/main/resources/application.yml or mounted as a config file) or overridden via environment variables using the FLOCI_ prefix with dots and dashes replaced by underscores.
URL configuration
Floci generates absolute URLs for certain response fields (SQS queue URLs, SNS subscription endpoints, pre-signed S3 URLs). Two settings control the hostname embedded in those URLs:
| Setting | Env variable | Default | Description |
|---|---|---|---|
floci.base-url |
FLOCI_BASE_URL |
http://localhost:4566 |
Full base URL used to build response URLs. Change the scheme, host, and port together. |
floci.hostname |
FLOCI_HOSTNAME |
(none) | Override only the hostname in base-url. Useful in Docker Compose where localhost is unreachable from other containers. |
When floci.hostname is set it replaces just the host portion of base-url,
leaving the scheme and port unchanged. Setting FLOCI_HOSTNAME: floci is
equivalent to changing base-url from http://localhost:4566 to
http://floci:4566.
Example — Docker Compose multi-container setup:
See Docker Compose — Multi-container networking for a full example.
Full Reference
The block below mirrors src/main/resources/application.yml, it's the effective set of keys Floci ships with. Some supported keys are omitted here (for example floci.init-hooks.*) but can still be provided via YAML or environment variables.
floci:
base-url: "http://localhost:4566" # Used to build response URLs (SQS QueueUrl unless sqs.endpoint-strategy is aws, SNS endpoints, etc.)
# hostname: "" # When set, overrides the host in base-url for multi-container Docker
default-region: us-east-1 # Also selects the partition (cn-north-1 -> aws-cn)
default-account-id: "000000000000"
partitions:
# id: aws # Pin the partition explicitly; derived from default-region when unset
strict: false # true rejects services AWS does not publish in the request's partition
allow-unknown-regions: false # true serves a scope region no partition publishes or matches by pattern
storage:
mode: memory # memory | persistent | hybrid | wal
persistent-path: ./data
# EFS access-point emulation for the shared local Docker volumes that back ECS
# efsVolumeConfiguration mounts. All opt-in; with no overrides a shared volume is a plain
# named volume (root:root 0755), so existing behaviour is unchanged. See docs/services/ecs.md.
efs:
# owner-uid: 1001 # CreationInfo.OwnerUid (set together with owner-gid)
# owner-gid: 1001 # CreationInfo.OwnerGid (set together with owner-uid)
# root-permissions: "2775" # CreationInfo.Permissions; 3-4 octal digits (4-digit carries setgid/sticky)
init-image: busybox:stable # image for the one-off chown/chmod of the volume root
# mount-user: "1001:1001" # PosixUser: run mounting containers as uid[:gid]
# mount-group-add: 2000 # supplementary gid added to mounting containers
wal:
# Also the cadence at which journaled stores under persistent mode (CloudWatch Logs events and
# metric datapoints, the S3 object index) fold their .wal file into the store's JSON file.
compaction-interval-ms: 30000
services:
ssm:
flush-interval-ms: 5000
dynamodb:
flush-interval-ms: 5000
sns:
flush-interval-ms: 5000
lambda:
flush-interval-ms: 5000
cloudwatchlogs:
flush-interval-ms: 15000
cloudwatchmetrics:
flush-interval-ms: 5000
secretsmanager:
flush-interval-ms: 5000
acm:
flush-interval-ms: 5000
opensearch:
flush-interval-ms: 5000
fis:
flush-interval-ms: 5000
dns:
# Extra hostname suffixes resolved to Floci's container IP by the embedded DNS server.
# The primary suffix (floci.hostname or derived from base-url) is always included.
# Useful when migrating from LocalStack — Lambda functions that hardcode
# localhost.localstack.cloud as their endpoint work without code changes.
# Via env var (comma-separated): FLOCI_DNS_EXTRA_SUFFIXES=localhost.localstack.cloud,other.internal
# extra-suffixes:
# - localhost.localstack.cloud
# Transparent endpoint injection: resolve every AWS partition's DNS and dual-stack
# suffix (amazonaws.com, api.aws, amazonaws.eu, amazonaws.com.cn and the rest; see
# environment-variables.md for the full list) and every subdomain to Floci's
# container IP inside spawned containers, so SDK clients built with explicit
# real-AWS endpoints (which override AWS_ENDPOINT_URL) land on the emulator.
# Live suffixes like api.aws and amazonaws.eu resolve to Floci while this is on.
# Combine with tls.enabled for clients that hardcode https://.
# Via env var: FLOCI_DNS_SPOOF_AWS_ENDPOINTS=true
spoof-aws-endpoints: false
auth:
validate-signatures: false # Set to true to verify SigV4 signatures for every service (S3: header, presigned URL, presigned POST; others: header)
presign-secret: local-emulator-secret # HMAC secret for S3 pre-signed URL verification
tls:
enabled: false # FLOCI_TLS_ENABLED — enable HTTPS on all endpoints
# cert-path: "" # FLOCI_TLS_CERT_PATH — PEM certificate file path
# key-path: "" # FLOCI_TLS_KEY_PATH — PEM private key file path
self-signed: true # FLOCI_TLS_SELF_SIGNED: auto-generate a cert signed by the local CA when no paths provided
protocols:
max-request-size: 2048 # FLOCI_PROTOCOLS_MAX_REQUEST_SIZE — max HTTP request body size in MB (legacy: floci.max-request-size / FLOCI_MAX_REQUEST_SIZE)
docker:
log-max-size: "10m" # Max size per container log file before rotation
log-max-file: "3" # Number of rotated log files to retain
docker-host: unix:///var/run/docker.sock # Docker daemon socket (shared by Lambda, RDS, ElastiCache)
max-connections: 1024 # Docker client connection pool; each live Lambda container holds 1
streaming-max-connections: 512 # Separate pool for container log-follow streams
docker-config-path: "" # Path to dir containing Docker's config.json (e.g. /root/.docker)
registry-credentials: [] # Per-registry explicit credentials for private registries
services:
ssm:
enabled: true
max-parameter-history: 5 # Max versions kept per parameter
sqs:
enabled: true
default-visibility-timeout: 30 # Seconds
max-message-size: 1048576 # Bytes (1 MiB, the AWS maximum)
clear-fifo-deduplication-cache-on-purge: false # When true, PurgeQueue clears SQS FIFO dedup and SNS FIFO topic dedup for topics subscribed to that queue
receipt-handle-secret: local-emulator-secret # HMAC secret that signs receipt handles
cloudwatch-metrics-enabled: true # Publish AWS/SQS queue metrics to CloudWatch once a minute
endpoint-strategy: floci # QueueUrl shape: floci is <base-url>/<account>/<name>, aws is https://sqs.<region>.<dns-suffix>/<account>/<name>
s3:
enabled: true
default-presign-expiry-seconds: 3600
lifecycle-sweep-enabled: true # Apply bucket lifecycle expiration rules in the background
lifecycle-sweep-interval-seconds: 60 # Seconds between lifecycle sweeps
dynamodb:
enabled: true
backend: native # native | local (forward calls to DynamoDB Local)
# local-endpoint: http://dynamodb-local:8000 # DynamoDB Local base URL, required when backend is local
local-connect-timeout-seconds: 2 # Seconds to wait for a connection to DynamoDB Local
local-request-timeout-seconds: 10 # Seconds to wait for DynamoDB Local to answer a forwarded request
sns:
enabled: true
lambda:
enabled: true
ephemeral: false # true = remove container after each invocation
docker-flags: "" # Extra Docker create flags for Lambda containers
ecr-base-uri: public.ecr.aws # Registry for Lambda runtime images (legacy: floci.ecr-base-uri / FLOCI_ECR_BASE_URI)
runtime-images: # Optional per-runtime image references
"python3.12": "registry.example/lambda-python:3.12"
honour-architectures: false # true = select the declared Lambda Docker architecture
default-memory-mb: 128
default-timeout-seconds: 3
runtime-api-base-port: 12000 # Port range for Lambda Runtime API
runtime-api-max-port: 12499 # One port per running container = concurrency ceiling
code-path: ./data/lambda-code # Where ZIP archives are stored
zip-max-entries: 100000 # Maximum ZIP entries extracted per deployment package
poll-interval-ms: 1000
async-retry-delay-seconds: 60 # Wait before the first retry of a failed Event invocation; the second waits twice this
container-idle-timeout-seconds: 300 # Remove idle containers after this
init-timeout-seconds: 10 # Time a cold runtime has to request its first invocation; the function's Timeout wins when longer
# warm-pool-max-per-function: # Idle containers kept per function (default max(4, cpus))
warm-pool-max-total: 0 # Idle containers kept across all functions; 0 = unbounded
region-concurrency-limit: 1000 # Concurrent executions ceiling per region
unreserved-concurrency-min: 100 # Minimum unreserved capacity PutFunctionConcurrency must leave
hot-reload:
enabled: false # true = enable bind-mount hot-reload via S3Bucket=hot-reload
# allowed-paths: # Optional allowlist of host paths that may be bind-mounted
# - /home/user/projects
# - /tmp
reactive-s3-sync:
enabled: true # Re-deploy a function when the S3 object it was deployed from is overwritten
async: false # true = re-deploy in the background so the upload does not wait
apigateway:
enabled: true
apigatewayv2:
enabled: true
iam:
enabled: true
enforcement-enabled: false # Set to true to enforce IAM policies on all requests
seed-deployer-principal: false # Set to true to create a local floci-deployer admin principal
networkfirewall:
enabled: true
servicequotas:
enabled: true
ram:
enabled: true
elasticache:
enabled: true
proxy-base-port: 6379
proxy-max-port: 6399
default-image: "valkey/valkey:8"
rds:
enabled: true
mock: false # true = clusters/instances created without Docker (useful for CI)
proxy-base-port: 7001
proxy-max-port: 7099
# endpoint-host: localhost # Hostname clients use; enables published-port translation in Docker
# Omit image overrides to adapt Floci's built-in images to EngineVersion.
# Uncomment an override to pin that engine to an exact image.
# default-postgres-image: "registry.example.com/postgres:16-alpine"
# default-mysql-image: "registry.example.com/mysql:8.0"
# default-mariadb-image: "registry.example.com/mariadb:11"
default-sql-server-image: "mcr.microsoft.com/mssql/server:2022-latest"
rds-data:
enabled: true
transaction-ttl-seconds: 180
database-resuming-exception-enabled: false
eventbridge:
enabled: true
scheduler:
enabled: true
cloudwatchlogs:
enabled: true
max-events-per-query: 10000
max-stored-events: 20000 # per account; oldest events are evicted once the store exceeds this
cloudwatchmetrics:
enabled: true
secretsmanager:
enabled: true
default-recovery-window-days: 30
kinesis:
enabled: true
kms:
enabled: true
cognito:
enabled: true
enforce-token-validity-limits: true # Reject app clients whose token validity is outside AWS's limits; false allows shorter tokens
stepfunctions:
enabled: true
cloudformation:
enabled: true
cloudcontrol:
enabled: true
create-worker-threads: 4 # Threads that run CreateResource provisioning
create-queue-capacity: 64 # Creates that may wait for a thread before ThrottlingException
acm:
enabled: true
validation-wait-seconds: 0 # Seconds before transitioning PENDING_VALIDATION → ISSUED
ses:
enabled: true
# smtp-host: mailpit # SMTP server for email relay (empty = store only)
# smtp-port: 1025
# smtp-user: ""
# smtp-pass: ""
# smtp-starttls: DISABLED # DISABLED, OPTIONAL, or REQUIRED
opensearch:
enabled: true
mock: false # true = metadata only, no Docker (useful for CI)
default-image: "opensearchproject/opensearch:2"
proxy-base-port: 9400
proxy-max-port: 9499
keep-running-on-shutdown: false # leave containers running after Floci stops
# docker network is inherited from floci.services.docker-network
ec2:
enabled: true
efs:
enabled: true
ecs:
enabled: true
mock: false # true = tasks go to RUNNING without Docker (useful for CI)
docker-network: floci-net # required for task-role credentials; must be user-defined
image-pull-behavior: default # as ECS_IMAGE_PULL_BEHAVIOR: default | always | once | prefer-cached
task-role-credentials:
enabled: false # vend real task IAM role credentials to task containers
ttl-seconds: 21600 # six hours, matching AWS
port: 51679 # Floci-side port; containers always use 169.254.170.2:80
appsync:
enabled: true
appconfig:
enabled: true
appconfigdata:
enabled: true
fis:
enabled: true
ecr:
enabled: true
registry-image: "registry:2"
registry-container-name: floci-ecr-registry
registry-base-port: 5100 # private loopback backing port range
registry-max-port: 5199
data-path: ./data/ecr
tls-enabled: false
keep-running-on-shutdown: true
uri-style: hostname # hostname | path
prefer-local-images: true
Initialization hooks
floci.init-hooks.* is accepted as an override but is not declared in the shipped application.yml. See Initialization Hooks for the full list of keys (shell-executable, timeout-seconds, shutdown-grace-period-seconds) and their defaults.
Service Limits
All keys in this table are declared on EmulatorConfig and accept environment variable overrides via the FLOCI_ prefix.
| Variable | Default | Description |
|---|---|---|
FLOCI_PROTOCOLS_MAX_REQUEST_SIZE |
2048 |
Max HTTP request body size in MB (legacy: FLOCI_MAX_REQUEST_SIZE) |
FLOCI_DEFAULT_REGION |
us-east-1 |
Default AWS region used in ARNs and response URLs |
FLOCI_DEFAULT_AVAILABILITY_ZONE |
us-east-1a |
Default AZ reported by EC2, RDS, and other AZ-aware services |
FLOCI_DEFAULT_ACCOUNT_ID |
000000000000 |
Default AWS account ID used in ARNs |
FLOCI_SERVICES_LAMBDA_ECR_BASE_URI |
public.ecr.aws |
Registry used when pulling Lambda runtime images (legacy: FLOCI_ECR_BASE_URI) |
FLOCI_SERVICES_LAMBDA_RUNTIME_IMAGES__PYTHON3_12__ |
(unset) | Image reference for python3.12; double underscores quote the dotted runtime key |
FLOCI_DNS_EXTRA_SUFFIXES |
(unset) | Comma-separated extra hostname suffixes the embedded DNS server resolves to Floci's container IP. E.g. localhost.localstack.cloud,localhost.example.internal |
FLOCI_SERVICES_SSM_MAX_PARAMETER_HISTORY |
5 |
Max parameter versions kept |
FLOCI_SERVICES_SQS_DEFAULT_VISIBILITY_TIMEOUT |
30 |
Default visibility timeout (seconds) |
FLOCI_SERVICES_SQS_MAX_MESSAGE_SIZE |
1048576 |
Max message size (bytes) |
FLOCI_SERVICES_SQS_CLEAR_FIFO_DEDUPLICATION_CACHE_ON_PURGE |
false |
When true, PurgeQueue clears the FIFO 5-minute deduplication cache for the target queue and matching SNS FIFO topic dedup entries |
FLOCI_SERVICES_SQS_RECEIPT_HANDLE_SECRET |
local-emulator-secret |
HMAC secret that signs receipt handles, so a handle that was edited or built by hand is rejected |
FLOCI_SERVICES_SQS_ENDPOINT_STRATEGY |
floci |
Shape of the returned QueueUrl. floci gives <FLOCI_BASE_URL>/<account>/<name> and aws gives https://sqs.<region>.<dns-suffix>/<account>/<name>. Both forms are accepted as input |
FLOCI_SERVICES_SQS_CLOUDWATCH_METRICS_ENABLED |
true |
Publish the AWS/SQS metrics of active queues to CloudWatch once a minute |
FLOCI_SERVICES_S3_DEFAULT_PRESIGN_EXPIRY_SECONDS |
3600 |
Pre-signed URL expiry |
FLOCI_SERVICES_DOCKER_NETWORK |
(unset) | Shared Docker network for Lambda, RDS, ElastiCache containers |
FLOCI_SERVICES_RDS_DATA_ENABLED |
true |
Enable the RDS Data API service |
FLOCI_SERVICES_RDS_DATA_TRANSACTION_TTL_SECONDS |
180 |
Idle timeout, in seconds, before leaked RDS Data API transactions expire |
FLOCI_SERVICES_RDS_DATA_DATABASE_RESUMING_EXCEPTION_ENABLED |
false |
Return HTTP 400 DatabaseResumingException during Aurora resume instead of waiting |
FLOCI_SERVICES_ECS_MOCK |
false |
Skip Docker; tasks go straight to RUNNING (useful for CI) |
FLOCI_SERVICES_ECS_DOCKER_NETWORK |
(unset) | Docker network for ECS task containers |
FLOCI_SERVICES_ECS_DEFAULT_MEMORY_MB |
512 |
Default memory (MB) when task definition omits it |
FLOCI_SERVICES_ECS_DEFAULT_CPU_UNITS |
256 |
Default CPU units when task definition omits it |
FLOCI_SERVICES_ECS_HOST_VOLUME_ROOTS |
(unset) | Comma-separated allowlist of parent directories for host volume bind mounts and container devices; by default (unset, and ALLOW_UNSAFE_HOST_VOLUMES=false) every host volume sourcePath and device hostPath is rejected |
FLOCI_SERVICES_ECS_ALLOW_UNSAFE_HOST_VOLUMES |
false |
Allow any host path, bypassing the host-volume-roots allowlist (traversal, bare root, and the Docker socket or an ancestor directory of it are still always rejected) |
FLOCI_SERVICES_ECS_RECONCILE_CONTAINERS_ON_STARTUP |
true |
Remove the ECS containers a previous run of this Floci left on the daemon before replacement tasks start |
FLOCI_SERVICES_ECS_IMAGE_PULL_BEHAVIOR |
default |
How task images are pulled at launch, as the ECS agent's ECS_IMAGE_PULL_BEHAVIOR: default, always, once or prefer-cached |
FLOCI_SERVICES_IAM_ENFORCEMENT_ENABLED |
false |
Enforce IAM identity-based policies on every request when true |
FLOCI_SERVICES_OPENSEARCH_MOCK |
false |
Skip Docker; domains appear active immediately (useful for CI) |
FLOCI_SERVICES_OPENSEARCH_KEEP_RUNNING_ON_SHUTDOWN |
false |
Leave OpenSearch containers running after Floci stops |
FLOCI_SERVICES_SES_SMTP_HOST |
(unset) | SMTP server host for SES email relay (empty = store only) |
FLOCI_SERVICES_SES_SMTP_PORT |
25 |
SMTP server port |
FLOCI_SERVICES_SES_SMTP_USER |
(unset) | SMTP authentication username |
FLOCI_SERVICES_SES_SMTP_PASS |
(unset) | SMTP authentication password |
FLOCI_SERVICES_SES_SMTP_STARTTLS |
DISABLED |
STARTTLS mode: DISABLED, OPTIONAL, or REQUIRED |
FLOCI_SERVICES_LAMBDA_HONOUR_ARCHITECTURES |
false |
Select the declared Lambda architecture for Docker image pulls and containers |
FLOCI_SERVICES_LAMBDA_ZIP_MAX_ENTRIES |
100000 |
Maximum number of entries accepted in a Lambda ZIP archive |
FLOCI_SERVICES_LAMBDA_HOT_RELOAD_ENABLED |
false |
Enable bind-mount hot-reload mode (S3Bucket=hot-reload) |
FLOCI_SERVICES_LAMBDA_HOT_RELOAD_ALLOWED_PATHS |
(unset) | Comma-separated list of host paths allowed as bind-mount roots; unset = any absolute path |
Enable FLOCI_SERVICES_LAMBDA_HONOUR_ARCHITECTURES only when the Docker host can run the
function architecture. Foreign architectures require Docker Desktop support or host emulation
such as binfmt_misc with QEMU. Floci does not fall back to the host architecture when this
setting is enabled.
Per-queue SQS redrive policy (maxReceiveCount) is configured at queue creation time via SetQueueAttributes / CreateQueue, not as a global default.
FLOCI_DEFAULT_AVAILABILITY_ZONE is declared in EmulatorConfig but not in the shipped application.yml, so it falls through to the @WithDefault value above when unset.
The flat keys floci.max-request-size / FLOCI_MAX_REQUEST_SIZE and floci.ecr-base-uri / FLOCI_ECR_BASE_URI moved into sub-structures in 2.x (floci.protocols.max-request-size and floci.services.lambda.ecr-base-uri). The old names still resolve — a FlociConfigRelocationsInterceptor maps them onto the new keys — so existing configs and env vars keep working.
Disabling Services
Set enabled: false for any service you don't need. Disabled services return a ServiceUnavailableException rather than silently ignoring calls.
Via environment variable — set to false for any FLOCI_SERVICES_<SERVICE>_ENABLED key. See Environment Variables Reference for the full list.
Logging
Floci uses standard Quarkus logging. The default effective level is INFO. Each service logs operation-level events at DEBUG (IDs and target resources) and full request/response payloads at TRACE — useful when diagnosing TestContainers-based test failures.
Floci ships with quarkus.log.min-level: TRACE, so raising a single category to TRACE is enough; you don't need to change the min-level yourself.
Enable TRACE for a service via environment variables:
# SQS: log SendMessage/ReceiveMessage/DeleteMessage bodies and attributes
QUARKUS_LOG_CATEGORY__IO_FLOCI_AWS_SERVICES_SQS__LEVEL=TRACE
# DynamoDB: log PutItem/GetItem/UpdateItem/DeleteItem items, Query/Scan counts
QUARKUS_LOG_CATEGORY__IO_FLOCI_AWS_SERVICES_DYNAMODB__LEVEL=TRACE
Or in application.yml:
quarkus:
log:
category:
"io.floci.aws.services.sqs":
level: TRACE
"io.floci.aws.services.dynamodb":
level: TRACE
TestContainers example:
new GenericContainer<>("floci/floci:latest")
.withExposedPorts(4566)
.withEnv("QUARKUS_LOG_CATEGORY__IO_FLOCI_AWS_SERVICES_SQS__LEVEL", "TRACE");
TRACE output includes the payload alongside the existing DEBUG line: