# floci

Free, open-source local AWS emulator. One `docker compose up`, no account, no feature gates. Built on Quarkus/Vert.x with JAX-RS routing, it answers AWS SDK and CLI calls on port `4566` — the same port LocalStack uses — and is meant as a drop-in replacement for LocalStack Community, which started requiring auth tokens and froze security updates in March 2026. Named after *cirrocumulus floccus*, the cloud formation that looks like popcorn.

## What it does

Floci speaks the AWS wire protocol for 46 services. Stateless services (SSM, SQS, SNS, IAM, STS, KMS, Secrets Manager, SES, Cognito, Kinesis, EventBridge, CloudWatch, Step Functions, CloudFormation, ACM, API Gateway, ELB v2, Auto Scaling, CodeDeploy, Backup, Route53, Transfer Family, Bedrock Runtime, …) and stateful ones (S3, DynamoDB, DynamoDB Streams) run in-process. Container-backed services start real Docker containers behind the AWS-shaped control plane.

The pitch against LocalStack Community: no auth token, ongoing security updates, ~24 ms startup vs ~3.3 s, ~13 MiB idle memory vs ~143 MiB, ~90 MB image vs ~1 GB, MIT license, plus a native binary (~40 MB). It also covers things LocalStack Community doesn't — API Gateway v2 / HTTP API, Cognito, ElastiCache with IAM auth, RDS with IAM auth, MSK, Athena with real SQL, Glue Data Catalog + Schema Registry, Data Firehose, ECS/EKS/EC2/CodeBuild — and fills in partial LocalStack coverage of IAM, STS, Kinesis, KMS, S3 Object Lock, DynamoDB Streams.

## How it works

**Real Docker integration.** Where in-process emulation would compromise fidelity — stateful databases, connection-heavy protocols, runtimes needing native execution — Floci runs actual containers and gets wire-compatible behavior against the real engine:

- **Lambda** → `public.ecr.aws/lambda/<runtime>` images, warm container pool, aliases, Function URLs, SQS/Kinesis/DDB-Streams event source mappings. Container-image functions pass `ImageUri` through, rewriting ECR repo URIs to the local endpoint.
- **ElastiCache** → `valkey/valkey:8`, full Redis/Valkey protocol, ACL-based IAM auth, SigV4 validation.
- **RDS** → `postgres:16-alpine`, `mysql:8.0`, `mariadb:11` — real engines, IAM auth via token, JDBC-compatible.
- **MSK** → `redpandadata/redpanda:latest`, real Kafka-compatible broker.
- **EC2** → AMI-mapped Linux containers (e.g. `public.ecr.aws/amazonlinux/amazonlinux:2023`), SSH key injection, UserData execution, IMDS (v1 + v2, port 9169) serving IAM credentials; plus VPCs, subnets, security groups, route tables, Elastic IPs.
- **ECS** → real container lifecycle from task definitions.
- **EKS** → `rancher/k3s:latest`, a live Kubernetes API server per cluster (mock mode also available).
- **CodeBuild** → runs the buildspec phases in a container, streams logs to CloudWatch Logs, uploads artifacts to S3 via `docker cp` (works in Docker-in-Docker).
- **OpenSearch** → `opensearchproject/opensearch:2`, full REST API.
- **ECR** → a shared `registry:2` container, so stock `docker push` / `docker pull` work against AWS-shaped repos.
- **Athena** → in-process API plus a DuckDB sidecar (`floci-duck`) that runs real SQL over S3 data through Glue-backed views; SerDe maps to `read_parquet` / `read_json_auto` / `read_csv_auto`.

All default images are overridable via `FLOCI_SERVICES_*_IMAGE` env vars. Docker-backed services need the Docker socket mounted (`-v /var/run/docker.sock:/var/run/docker.sock -u root`). These services support real SigV4 signing and IAM auth — the same flow as production AWS.

**Storage modes.** Configured globally via `FLOCI_STORAGE_MODE` or per service:

| Mode | Behavior | Durability |
|---|---|---|
| `memory` (default) | entirely in-RAM, lost on stop | none |
| `persistent` | loaded at startup, flushed on graceful shutdown | medium |
| `hybrid` | in-memory speed, async flush every 5s | good |
| `wal` | write-ahead log, every mutation logged before responding | highest |

`memory` for CI; `hybrid` for local dev with state across restarts.

**Multi-account isolation.** No config needed: if `AWS_ACCESS_KEY_ID` is exactly 12 digits, Floci uses it as the account ID and resources are namespaced per account. Any other key format falls back to `FLOCI_DEFAULT_ACCOUNT_ID` (`000000000000`).

## Migrating from LocalStack

Swap the image — `localstack/localstack` → `floci/floci:latest` (or `floci/floci:latest-compat` for init scripts that call `aws`/boto3, which bundles Python 3 + AWS CLI + boto3). LocalStack env vars are translated automatically: `LOCALSTACK_HOST`→`FLOCI_HOSTNAME`, `PERSISTENCE=1`→`FLOCI_STORAGE_MODE=persistent`, `LAMBDA_DOCKER_NETWORK`→`FLOCI_SERVICES_LAMBDA_DOCKER_NETWORK`, `LAMBDA_REMOVE_CONTAINERS=1`→`FLOCI_SERVICES_LAMBDA_EPHEMERAL=true`, `DEBUG=1`→`QUARKUS_LOG_LEVEL=DEBUG`. Init scripts under `/etc/localstack/init/` run unchanged; `/_localstack/init` and `/_localstack/health` are still served. `LOCALSTACK_PARITY=false` opts out of the translation.

## Usage

```yaml
# docker-compose.yml
services:
  floci:
    image: floci/floci:latest
    ports:
      - "4566:4566"
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock   # for container-backed services
```

```bash
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test

aws s3 mb s3://my-bucket
aws sqs create-queue --queue-name my-queue
aws dynamodb list-tables
```

Point any AWS SDK at `http://localhost:4566` with an `endpointOverride` / `endpoint_url` / `endpoint` — no other changes. Credentials and region can be anything.

## Limitations

- Some services are stubs: Bedrock Runtime returns dummy Converse/InvokeModel responses (streaming → 501); Textract returns API-compatible stubs with fake block data.
- Container-backed services require a usable Docker socket — won't work in environments where that's unavailable, and image pulls add startup cost on first use.
- It's a young project (single org `floci-io`, image recently renamed from `hectorvent/floci` to `floci/floci`). Tracked on [[watchlist]] — re-check maturity, contributor count, and release cadence.
- Fidelity is best-effort emulation; not every edge case of every AWS API is covered. See the [Services Overview](https://floci.io/floci/services/) for per-service operation counts.

Related: [[ark-ecs]] (ECS-focused tooling), [[atomicapp]] (container app packaging). For the broader "local cloud emulator" niche this competes in the LocalStack space.

Repo: <https://github.com/floci-io/floci> · MIT · Java/Quarkus · docs at <https://floci.io>
