Floci:本地运行任意云服务
本文目录
Floci#
任意云服务,本地运行。
轻盈、蓬松,永远免费
无需账号。无需认证令牌。无功能限制。只需 docker compose up。
快速开始 · 功能特性 · 支持服务 · SDK 集成 · Testcontainers · 迁移 · 文档
什么是 Floci?#
Floci 是一个免费、开源的本地 AWS 模拟器(local AWS emulator),用于开发、测试和 CI。
它在你自己的机器上提供 AWS 形态的服务,无需云账号、认证令牌或付费功能门槛。将你的 AWS SDK、CLI、Terraform、CDK、OpenTofu 或测试套件指向 http://localhost:4566,即可继续使用现有工作流。
已经在使用 LocalStack?Floci 可直接替换(drop-in replacement):替换镜像即可继续。参见《从 LocalStack 迁移》。
Floci 是 Floci 模拟器家族中的 AWS 成员,名字来自 floccus——一种看起来像爆米花的云。
| 模拟器 | 云平台 | 端口 |
|---|---|---|
| floci | AWS | 4566 |
| floci-az | Azure | 4577 |
| floci-gcp | GCP | 4588 |
| floci-oci | OCI | 4599 |
快速开始#
运行 Floci 最快的方式是使用官方 CLI:
floci start
没有 Docker?每个发行版还提供独立的 floci-aws 二进制文件,适用于 Linux、macOS 和 Windows;参见《原生二进制文件》。
导出 AWS 环境变量:
eval $(floci env)
像平常一样使用现有的 AWS 工具:
aws s3 mb s3://my-bucket
aws dynamodb create-table \
--table-name demo-table \
--attribute-definitions AttributeName=pk,AttributeType=S \
--key-schema AttributeName=pk,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
aws dynamodb list-tables
观看运行#
这段简短演示展示了 CLI 流程:启动 Floci、导出本地 AWS 环境、运行标准 AWS CLI 命令,然后停止模拟器。
floci-cli-demo.mp4
所有 AWS 服务均可通过 http://localhost:4566 访问。任何已发布的 AWS 区域都可用,覆盖所有分区。除非你显式启用更严格的服务级认证检查,凭据可以是任意非空值。
更喜欢 Docker Compose?#
创建 compose.yaml 文件:
services:
floci:
image: floci/floci:latest
ports:
- "4566:4566"
启动 Floci:
docker compose up
然后手动配置 AWS 环境:
export AWS_ENDPOINT_URL=http://localhost:4566
export AWS_DEFAULT_REGION=us-east-1
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
仍在使用旧的 hectorvent/floci 镜像?#
更新你的镜像名称:
# 之前
image: hectorvent/floci:latest
# 之后
image: floci/floci:latest
旧的 hectorvent/floci 仓库已不再接收更新。
Web 控制台#
Floci 附带一个浏览器控制台,用于检查本地模拟器中的资源。
访问地址:http://localhost:4566/_floci/ui
启动时不会运行任何东西。首次请求会拉取控制台镜像,将其作为 sidecar 容器启动在 Floci 的 Docker 网络上,把 Floci 自身可达地址加上标准 AWS 环境交给它,轮询其健康端点,并在其报告能够连接 Floci 后重定向浏览器。sidecar 的端口由 Docker 绑定,因此不需要你自己配置 ports: 条目,其日志会流式写入 CloudWatch Logs 的 /floci/ui 下。
启动容器需要 Docker socket:
services:
floci:
image: floci/floci:latest
ports:
- "4566:4566"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
| 变量 | 默认值 | 说明 |
|---|---|---|
| FLOCI_SERVICES_UI_ENABLED | true | 启用控制台 sidecar |
| FLOCI_SERVICES_UI_IMAGE | floci/floci-ui:0.7.0 | 要运行的控制台镜像 |
| FLOCI_SERVICES_UI_CONTAINER_NAME | floci-ui | sidecar 容器名称 |
| FLOCI_SERVICES_UI_PORT | 4500 | 控制台发布到的主机端口 |
| FLOCI_SERVICES_UI_BIND_ADDRESS | (无) | 发布端口所用的主机接口。未设置时发布到所有接口;当 Floci 自身端口仅绑定回环地址时设为 127.0.0.1 |
| FLOCI_SERVICES_UI_KEEP_RUNNING_ON_SHUTDOWN | false | Floci 停止时让 sidecar 继续运行 |
运行不同的控制台#
控制台并不固定为 Floci 自带的那个。任何实现了 Floci 控制台约定的控制台,只需一个镜像名称即可运行:监听 PORT 指定的端口,提供 GET /api/health,并通过 AWS_ENDPOINT_URL 与 Floci 通信。
environment:
FLOCI_SERVICES_UI_IMAGE: acme/my-console:1.0
如果某个控制台与约定默认值不同,它会在自己的 io.floci.console.* 镜像标签中说明,因此其运维人员无需手动配置。例如 StackPort 监听 8080 而不是 4500;对于早于这些标签的镜像,需要手动指定:
environment:
FLOCI_SERVICES_UI_IMAGE: davireis/stackport:latest
FLOCI_SERVICES_UI_CONTAINER_NAME: floci-stackport
FLOCI_SERVICES_UI_PORT: "8080"
FLOCI_SERVICES_UI_INTERNAL_PORT: "8080"
Floci Dash 是另一个例子。它遵循 PORT,因此只需指定它确实不同的两项:
environment:
FLOCI_SERVICES_UI_IMAGE: ghcr.io/ofsazib/floci-dash:latest
FLOCI_SERVICES_UI_CONTAINER_NAME: floci-dash
FLOCI_SERVICES_UI_ENDPOINT_ENV: FLOCI_URL
FLOCI_SERVICES_UI_STATUS_PATH: /api/healthz
端点本身从不需要手动配置:Floci 启动时解析自身可达地址,并将其注入为 AWS_ENDPOINT_URL。
完整参考:Web 控制台 和 控制台约定 v1。
功能特性#
无需云账号的本地 AWS#
在本地运行 AWS 兼容服务,无需 AWS 账号、认证令牌或付费功能门槛。
在对保真度有要求的地方使用真实 Docker#
Lambda、RDS、Neptune、ElastiCache、MSK、ECS、EC2、EKS、OpenSearch、CodeBuild 以及 Managed Service for Apache Flink 使用真实的 Docker 支撑执行,而不是浅层模拟。
即插即用的 AWS 兼容性#
将标准 AWS 客户端指向 http://localhost:4566。现有凭据、区域、SDK、CLI 命令和 IaC 工作流保持熟悉。
Terraform 可以通过 Floci 使用标准 HashiCorp AWS provider 在本地预置 AWS 形态的资源。provider 配置、资源示例以及可选的模拟 S3 状态请参见《Terraform 与 Floci》指南。
快到足以用于 CI#
原生镜像在毫秒级启动,并保持低空闲内存,适合本地开发和测试流水线。
可配置的持久化#
根据所需的持久性配置,选择内存、持久化、混合和预写日志(write-ahead log)存储。
为什么选择 Floci?#
LocalStack 社区版于 2026 年 3 月停止服务,要求认证令牌并冻结安全更新。Floci 是没有任何附加条件的替代方案。
| 能力 | Floci | LocalStack 社区版 |
|---|---|---|
| 需要认证令牌 | 否 | 是 |
| 安全更新 | 有 | 冻结 |
| 启动时间 | 约 24 ms | 约 3.3 s |
| 空闲内存 | 约 13 MiB | 约 143 MiB |
| Docker 镜像大小 | 约 90 MB | 约 1.0 GB |
| 许可证 | MIT | 受限 |
| API Gateway v2 / HTTP API | 支持 | 不支持 |
| Cognito | 支持 | 不支持 |
| RDS、ElastiCache、MSK | 真实 Docker | 不支持 |
| Neptune(图数据库 + Gremlin WebSocket) | 真实 Docker | 不支持 |
| DocumentDB(MongoDB 兼容) | 真实 Docker | 不支持 |
| ECS、EC2、EKS | 真实 Docker | 不支持 |
| CodeBuild | 真实 Docker 执行 | 不支持 |
| 原生二进制 | 约 40 MB | 不支持 |
广泛的 AWS 覆盖。永久免费。完整的模拟服务列表请参见《服务总览》。
架构概览#
flowchart LR
Client["AWS SDK / CLI"]
subgraph Floci ["Floci, port 4566"]
Router["HTTP Router\nJAX-RS / Vert.x"]
subgraph Stateless ["Stateless Services"]
A["SSM · SQS · SNS\nIAM · STS · KMS\nSecrets Manager · SES\nCognito · Kinesis\nEventBridge · Scheduler · AppConfig\nCloudWatch · Step Functions\nCloudFormation · ACM · Config · CloudTrail\nAPI Gateway · AppSync · ELB v2 · Auto Scaling\nElastic Beanstalk · CodeDeploy · CodePipeline · Backup · FIS · Bedrock Runtime · Bedrock AgentCore · Route53 · Transfer"]
end
subgraph Stateful ["Stateful Services"]
B["S3 · DynamoDB\nDynamoDB Streams"]
end
subgraph Containers ["Container Services"]
C["Lambda\nElastiCache\nRDS\nNeptune\nECS\nEC2\nMSK\nEKS\nOpenSearch\nCodeBuild\nManaged Flink"]
D["Athena -> floci-duck\nDuckDB sidecar"]
end
Router --> Stateless
Router --> Stateful
Router --> Containers
Stateless & Stateful --> Store[("StorageBackend\nmemory · hybrid · persistent · wal")]
end
Docker["Docker Engine"]
Client -->|"HTTP :4566\nAWS wire protocol"| Router
Containers -->|"Docker API\nIAM / SigV4 auth"| Docker
支持的服务#
Floci 支持对应用服务、数据服务、事件、身份、基础设施、计费以及容器支撑工作负载的本地模拟。
| 类别 | 服务 |
|---|---|
| 核心应用服务 | S3、SQS、SNS、DynamoDB、Lambda、Lambda MicroVM、Lambda Web Functions、IAM、STS、KMS、Payment Cryptography、Secrets Manager、SSM |
| 事件与工作流 | EventBridge、EventBridge V2、EventBridge Pipes、EventBridge Scheduler、Step Functions、SWF、CloudWatch Logs、CloudWatch Metrics、CloudWatch OAM、CloudWatch RUM、Managed Prometheus (AMP) |
| API 与身份 | API Gateway REST、API Gateway v2、AppSync、Cognito、Cognito Identity、ACM、Route53、Route 53 Resolver、Cloud Map、Global Accelerator |
| 容器与计算 | ECS、EC2、Lightsail、EKS、MWAA、ECR、EFS、CodeBuild、CodeDeploy、CodePipeline、CodeGuru Reviewer、CodeArtifact、AWS Batch、Auto Scaling、Application Auto Scaling、Elastic Beanstalk、ELB v2、ELB Classic |
| 数据、分析与 AI | Athena、Glue、Lake Formation、EMR、EMR Serverless、Redshift、Redshift Data API、Redshift Serverless、Firehose、Managed Service for Apache Flink、OpenSearch、S3 Tables、S3 Vectors、Textract、Transcribe、Comprehend、Rekognition、Translate、Bedrock、Bedrock Runtime、Bedrock AgentCore、Bedrock AgentCore Control、SageMaker |
| 数据库与缓存 | Aurora DSQL、RDS、RDS Data API、Neptune、DocumentDB、DMS、MemoryDB、ElastiCache、Timestream for InfluxDB |
| 消息与传输 | SES、Kinesis、MSK、Amazon MQ、Transfer Family、DataSync、IoT Core、Amazon Connect、Amazon AppIntegrations |
| 安全与治理 | AWS Network Firewall、AWS RAM、Service Quotas、WAF v2、GuardDuty、Amazon Inspector、CloudTrail、CloudFront、Resource Groups Tagging API、Resource Explorer 2、CloudHSM v2、Organizations、AWS Account Management、IAM Access Analyzer、IAM Identity Center (SSO Admin、OIDC、Access Portal、SCIM)、Identity Store、Amazon Macie、Amazon Detective、Security Hub、Amazon Verified Permissions、Control Catalog、Control Tower、Service Catalog、AWS Marketplace |
| 成本与计费 | AWS Budgets、Pricing、Cost Explorer、Cost and Usage Reports、BCM Pricing Calculator、BCM Data Exports |
| 韧性、备份与配置 | AWS FIS、AWS Backup、Amazon Data Lifecycle Manager、AWS Config、AppConfig、AppConfigData、CloudFormation、Cloud Control API |
操作级别的兼容性请参见《服务总览》。
详细服务说明#
| 服务 | 工作方式 | 主要特性 |
|---|---|---|
| SSM | 进程内 + EC2 容器 | Parameter Store(版本历史、标签、SecureString、打标签);Run Command(SendCommand、GetCommandInvocation、直接执行 EC2 容器、代理轮询) |
| SQS | 进程内 | 标准队列和 FIFO 队列、DLQ、可见性超时、批量操作、打标签 |
| SNS | 进程内 | 主题、订阅、SQS、Lambda 和 HTTP 投递、打标签 |
| S3 | 进程内 | 版本控制、分段上传、预签名 URL、对象锁、对象注解、事件通知 |
| S3 Vectors | 进程内 | 向量桶、索引、put / get / list / delete 向量、余弦相似度查询 |
| DynamoDB | 进程内 | GSI、LSI、Query、Scan、TTL、事务、批量操作;带分片迭代器和 Lambda 事件源映射的 Streams |
| Lambda | 真实 Docker | 运行时环境、执行模型、热容器池、别名、Function URL |
| API Gateway REST | 进程内 | 资源、方法、阶段、Lambda 代理、MOCK 集成、AWS 集成 |
| API Gateway v2 | 进程内 | HTTP API、路由、集成、JWT 授权器、阶段 |
| AppSync | 进程内 | GraphQL API 管理 API、schema 注册表、AWS 标量、域名、通道命名空间 |
| IAM | 进程内 | 用户、角色、组、策略、实例配置文件、访问密钥;STS AssumeRole、WebIdentity、SAML、GetFederationToken、GetSessionToken |
| Cognito | 进程内 | 用户池、应用客户端、认证流程、JWKS 和 OpenID well-known 端点 |
| KMS | 进程内 | 加密、解密、签名、验证、数据密钥、别名 |
| Payment Cryptography | 进程内 | 具有真实 AES-256 密钥材料和校验值的密钥、别名、打标签 |
| Kinesis | 进程内 | 流、分片、增强型扇出、拆分与合并 |
| Secrets Manager | 进程内 | 版本控制、资源策略、打标签 |
| Step Functions | 进程内 | ASL 执行、任务令牌、执行历史 |
| SWF | 进程内 | 决策任务和活动任务、定时器、子工作流、超时、真实 Lambda 调用 |
| CloudFormation | 进程内 | 堆栈、变更集、资源预置、StackSets(跨账号实例) |
| EventBridge | 进程内 | 自定义总线、规则、SQS、SNS 和 Lambda 目标 |
| EventBridge V2 | 进程内 | 事件总线和过滤订阅者投递到 SQS |
| EventBridge Pipes | 进程内 | 基于轮询器的集成,将 SQS、Kinesis、DynamoDB 和 MSK 源连接到目标,支持可选过滤 |
| EventBridge Scheduler | 进程内 | 调度组、调度、灵活时间窗口、重试策略、DLQ |
| CloudWatch Logs | 进程内 | 日志组、日志流、摄取、过滤 |
| CloudWatch Metrics | 进程内 | 自定义指标、统计信息、告警 |
| CloudWatch OAM | 进程内 | 完整的 15 个操作接收端、策略、跨账号链接和打标签 API |
| ElastiCache | 真实 Docker | Redis / Valkey 协议、IAM 认证、SigV4 校验 |
| MemoryDB | 真实 Docker | 通过真实容器提供 Redis / Valkey 协议;JSON 1.1 控制面;复用 ElastiCache RESP 代理 |
| Aurora DSQL | 真实 Docker,可用模拟模式 | 每个集群一个 PostgreSQL 16,位于 TLS 端点之后,支持 IAM 令牌认证、AWS IAM GRANT 角色映射;尚不支持 DSQL 的限制和异步索引 |
| RDS | 真实 Docker | PostgreSQL、MySQL、MariaDB、IAM 认证、JDBC 兼容引擎 |
| Timestream for InfluxDB | 真实 Docker,可用模拟模式 | 通过 influxdb:2.7 提供 InfluxDB 2.x 数据库实例和只读副本集群;初始认证密钥存放在 Secrets Manager;通过 influx CLI 备份和恢复 |
| RDS Data API | 基于真实 RDS 容器的 REST JSON | 对本地 MySQL / MariaDB RDS 资源执行原始 SQL 和事务 |
| Neptune | 真实 Docker | 通过 TinkerPop Gremlin Server(默认)或 Neo4j 提供图数据库,后者用于 openCypher/Bolt(NEPTUNE_DB_TYPE);RDS 形态的控制面;8182 端口上的 SigV4 代理 |
| DocumentDB | 真实 Docker,可用模拟模式 | 通过真实 MongoDB 容器提供 MongoDB 兼容集群;RDS 形态的控制面;27017 端口上的 MongoDB 线协议 |
| MSK | 真实 Docker | 通过 Redpanda 提供 Kafka 兼容 broker |
| Amazon MQ | 真实 Docker | 通过 rabbitmq:3-management 提供 RabbitMQ broker;AMQP + 管理控制台 |
| Athena | 进程内 + DuckDB sidecar | 对 S3 和 Glue 支撑的视图执行真实 SQL |
| Glue | 进程内 | 数据目录、schema 注册表、供 Athena 使用的表 |
| EMR | 进程内 | 集群(作业流)生命周期、实例组和实例队列(包括调整大小)、引导操作、步骤、安全配置、扩展和终止策略、阻止公共访问、打标签 |
| Data Firehose | 进程内 | 流式投递、带 GZIP/ZIP/Snappy 压缩的缓冲刷新到 S3 |
| Managed Service for Apache Flink | 真实 Docker | Kinesis Analytics V2 控制面;StartApplication 启动真实 Flink 集群(JobManager + TaskManager,每个 RuntimeEnvironment 一个镜像),从本地 S3 拉取应用 JAR 并提交作业 |
| ECS | 真实 Docker | 集群、任务定义、任务、服务、容量提供者、任务集 |
| EC2 | 真实 Docker | RunInstances 启动容器、SSH 密钥注入、UserData、IMDS、VPC 资源 |
| Lightsail | 进程内 | 实例、磁盘、静态 IP、密钥对、端口、标签、区域、blueprint、bundle、操作 |
| ACM | 进程内 | 证书签发和验证生命周期 |
| ECR | 进程内 + 真实 registry | 仓库、docker push / pull、镜像支撑的 Lambda 函数 |
| Resource Groups Tagging API | 进程内 | GetResources、给资源打标签/取消标签、跨服务的标签键和值发现 |
| SES | 进程内 | v1 和 v2 API:发送邮件、原始邮件、身份验证、DKIM、模板、配置集、账号发送 |
| OpenSearch | 真实 Docker | 域 CRUD、标签、版本、实例类型、升级桩 |
| AppConfig | 进程内 | 应用、环境、配置文件、托管版本、部署 |
| AppConfigData | 进程内 | 配置会话和动态配置检索 |
| Bedrock | 进程内 | 控制面上的护栏生命周期、版本和标签 |
| Bedrock Runtime | 进程内桩 | 用于本地开发的虚拟 Converse 和 InvokeModel 响应 |
| Bedrock AgentCore | 进程内桩 | 有状态控制面(agent 运行时、网关、内存、工作负载身份);预置的 InvokeAgentRuntime 响应 |
| EKS | 真实 Docker,可用模拟模式 | 带实时 Kubernetes API server 的 k3s 集群 |
| MWAA | 真实 Docker,可用模拟模式 | 每个环境真实 Apache Airflow(LocalExecutor)+ Postgres 元数据库;web/CLI 代理;S3 支撑的 DAG 同步 |
| ELB v2 | 进程内 | ALB、NLB、目标组、监听器、路由规则、Lambda 目标、标签 |
| CodeBuild | 进程内 + 真实 Docker | 真实 buildspec 执行、CloudWatch 日志、S3 产物 |
| CodeDeploy | 进程内 + Lambda 流量切换 | 部署组、配置、生命周期钩子、自动回滚 |
| CodePipeline | 进程内编排 | 管道、执行、S3 产物、审批、本地提供者、自定义 worker |
| AWS Network Firewall | 进程内 | DescribeFirewall,附带稳定的模拟端点挂载,供基础设施工具使用 |
| Service Quotas | 进程内 | 生成的配额目录,带宽松的静态值;CodeBuild 和 Lambda 并发的真实配额代码 |
| AWS RAM | 进程内 | EnableSharingWithAwsOrganization 选择加入 |
| AWS Batch | 进程内 | 计算环境、作业队列、作业定义、作业提交和生命周期 |
| Auto Scaling | 进程内 + 协调器 | 启动配置、ASG、期望容量协调、生命周期钩子 |
| Application Auto Scaling | 进程内 | 可扩展目标、目标跟踪和步进扩展策略、CloudWatch 告警创建、打标签(策略会存储但不生效) |
| Elastic Beanstalk | 进程内 | 应用、应用版本、环境、配置模板、平台和解决方案栈元数据 |
| AWS Backup | 进程内 | 保管库、备份计划、选择、模拟作业生命周期、恢复点 |
| Amazon Data Lifecycle Manager | 进程内 | 生命周期策略和标签管理;调度会存储但不会创建快照或 AMI |
| AWS FIS | 进程内 | 模板、实验、目标账号、操作和目标发现、安全杆、打标签和分页的全部 26 个管理 API;实验执行是安全的控制面模拟,不会向其他服务注入故障 |
| AWS Config | 进程内 | 配置规则、评估驱动的合规(PutEvaluations、合规详情和摘要)、配置记录器、投递通道、保留配置、一致性包、打标签 |
| Organizations | 进程内 | 组织、根、嵌套 OU、成员账号、所有策略类型(含 FullAWSAccess 和有效策略继承)、可信服务访问、委派管理员、资源策略,以及完整的邀请/握手流程;创建的账号是可用的 Floci 账号,成员账号可以读取其所属组织 |
| CloudTrail | 进程内 | 跟踪、事件选择器(带桶/前缀匹配的 S3 数据事件)、StartLogging/StopLogging、按 AWS 形态的键路径定时向目标桶发送 gzip 日志文件、IAM 拒绝路径发出 AccessDenied 记录 |
| CloudFront | 进程内 | 分配、源、缓存行为、失效、打标签 |
| WAF v2 | 进程内 | Web ACL、IP 集、正则模式集、规则组、日志配置、资源关联、打标签(REGIONAL 和 CLOUDFRONT 范围) |
| AWS Resource Groups | 进程内 | 五个容量池操作:存储的组、验证的 EC2 预留成员资格、作用域分页和组删除;没有动态查询或容量分配 |
| Resource Explorer 2 | 进程内 | 全部 32 个管理 API:索引和视图生命周期、多区域设置任务、完整的搜索查询语法和打标签;30 个服务暴露其资源供搜索,实时收集而非来自索引 |
| Route53 | 进程内 | 托管区域、SOA 和 NS 记录、资源记录集、变更跟踪、打标签 |
| Cloud Map | 进程内 | HTTP 和 DNS 命名空间、服务、实例注册、发现查询、操作、打标签 |
| Transfer Family | 进程内 | 服务器生命周期、用户管理、SSH 密钥导入、打标签 |
| Textract | 进程内桩 | API 兼容桩、虚拟块数据、异步作业模拟 |
| Transcribe | 进程内桩 | 转录作业和自定义词汇表;作业立即完成,无真实音频处理 |
| Pricing | 进程内 + 静态快照 | 产品发现、属性、价格清单文件、分页 |
| Cost Explorer | 进程内 | 从 Floci 资源状态和价格快照合成的成本 |
| Cost and Usage Reports | 进程内 + floci-duck sidecar | CUR 2.0 和 FOCUS 1.2 列、账号范围存储、Parquet 输出 |
| BCM Pricing Calculator | 进程内 | 工作负载估算的创建、使用定价、读取和删除生命周期 |
| BCM Data Exports | 进程内 | 导出的生命周期、执行、更新和删除操作 |
真实 Docker 集成#
当进程内模拟会降低保真度时,Floci 使用真实 Docker 容器。这适用于有状态数据库、连接密集型协议、运行时和构建系统。
| 服务 | 默认镜像 | 真实的部分 |
|---|---|---|
| Lambda | public.ecr.aws/lambda/<runtime> | AWS 运行时环境、执行模型、热容器池 |
| ElastiCache | valkey/valkey:8 | Redis / Valkey 协议、基于 ACL 的 IAM 认证、SigV4 校验 |
| RDS PostgreSQL | postgres:16-alpine | PostgreSQL 引擎、IAM 认证、JDBC 兼容访问 |
| RDS MySQL / Aurora | mysql:8.0 | MySQL 引擎、IAM 认证、JDBC 兼容访问 |
| RDS MariaDB | mariadb:11 | MariaDB 引擎、IAM 认证、JDBC 兼容访问 |
| Neptune | tinkerpop/gremlin-server:3.7.3 | TinkerPop Gremlin Server;8182 端口上的 Gremlin WebSocket;SigV4 认证代理 |
| Neptune(openCypher) | neo4j:5-community | 当 FLOCI_SERVICES_NEPTUNE_DB_TYPE=neo4j 时使用 Neo4j 后端;通过 Bolt 提供 openCypher |
| DocumentDB | mongo:7.0 | MongoDB 引擎;27017 端口上的 MongoDB 线协议 |
| MSK | redpandadata/redpanda:latest | 通过 Redpanda 提供 Kafka 兼容 broker |
| Amazon MQ | rabbitmq:3-management | RabbitMQ broker;5672 端口 AMQP,15672 管理控制台 |
| Managed Service for Apache Flink | apache/flink:<version> | Apache Flink JobManager;按 RuntimeEnvironment 选择镜像(FLINK-1_15 … FLINK-1_20,FLINK-2_0 … FLINK-2_3) |
| EC2 | AMI 映射的 Linux 镜像 | Linux 容器、SSH 密钥注入、UserData、IMDS、IAM 凭据 |
| ECS | 用户指定的任务镜像 | 容器生命周期、启动、停止、健康检查 |
| EKS | rancher/k3s:latest | 通过 k3s 提供 Kubernetes API server |
| MWAA | apache/airflow:<version>-python3.12 + postgres:16-alpine | 真实 Apache Airflow(LocalExecutor:scheduler + webserver)及其自带 Postgres 元数据库;通过 Floci 代理访问 webserver/CLI |
| CodeBuild | 用户指定的环境镜像 | Buildspec 执行、日志流式传输、S3 产物上传 |
| OpenSearch | opensearchproject/opensearch:2 | 带 REST API 的完整 OpenSearch 引擎 |
| ECR | registry:2 | 用于 docker push 和 docker pull 的 OCI 兼容 registry |
| Verified Permissions | floci/floci-sidecar-cedar:1.1.0 | 通过 Floci sidecar 进行 Cedar 4 策略解析、schema 校验和授权决策 |
| AppSync | floci/floci-sidecar-graphql:0.2.0 | 通过 Floci sidecar 进行 graphql-java schema 校验、查询规划和执行 |
Docker 支撑的服务需要 Docker socket:
docker run -d --name floci \
-p 4566:4566 \
-v /var/run/docker.sock:/var/run/docker.sock \
-u root \
floci/floci:latest
覆盖默认镜像#
| 变量 | 默认值 |
|---|---|
| FLOCI_SERVICES_ELASTICACHE_DEFAULT_IMAGE | valkey/valkey:8 |
| FLOCI_SERVICES_RDS_DEFAULT_POSTGRES_IMAGE | postgres:16-alpine |
| FLOCI_SERVICES_RDS_DEFAULT_MYSQL_IMAGE | mysql:8.0 |
| FLOCI_SERVICES_RDS_DEFAULT_MARIADB_IMAGE | mariadb:11 |
| FLOCI_SERVICES_MSK_DEFAULT_IMAGE | redpandadata/redpanda:latest |
| FLOCI_SERVICES_OPENSEARCH_DEFAULT_IMAGE | (未设置——镜像按请求的 EngineVersion 解析) |
| FLOCI_SERVICES_KINESIS_ANALYTICS_DEFAULT_IMAGE | (未设置;按 RuntimeEnvironment 选择) |
| FLOCI_SERVICES_NEPTUNE_DEFAULT_IMAGE | tinkerpop/gremlin-server:3.7.3 |
| FLOCI_SERVICES_NEPTUNE_DEFAULT_NEO4J_IMAGE | neo4j:5-community |
| FLOCI_SERVICES_DOCDB_DEFAULT_IMAGE | mongo:7.0 |
| FLOCI_SERVICES_EKS_DEFAULT_IMAGE | rancher/k3s:latest |
| FLOCI_SERVICES_MWAA_DEFAULT_POSTGRES_IMAGE | postgres:16-alpine |
| FLOCI_SERVICES_ECR_REGISTRY_IMAGE | registry:2 |
| FLOCI_SERVICES_LAMBDA_ECR_BASE_URI | public.ecr.aws |
持久化与存储模式#
Floci 可以根据工作流在速度和持久性之间取舍。通过 FLOCI_STORAGE_MODE 配置默认模式,或按服务覆盖存储方式。
| 模式 | 行为 | 最适合 | 持久性 |
|---|---|---|---|
| memory | 完全在内存中。容器停止后数据丢失。 | CI 和临时测试 | 无 |
| persistent | 启动时加载,并在每次写操作时立即刷盘。 | 需要立即持久化的简单本地状态保留 | 中等 |
| hybrid | 内存性能,每 5 秒周期性异步刷盘。 | 本地开发 | 良好 |
| wal | 预写日志。每次变更在响应前都会记录。 | 最高持久性 | 最高 |
使用 memory 进行快速测试运行。如果希望在容器重启后保留状态而又不想增加太多开销,请使用 hybrid。
更多细节请参见《存储配置》文档。
多账号隔离#
Floci 无需额外配置即可支持按账号隔离资源。如果 AWS_ACCESS_KEY_ID 恰好是 12 位数字,Floci 会将其用作账号 ID。一个账号创建的资源对另一个账号不可见。
AWS_ACCESS_KEY_ID=111111111111 aws sqs create-queue --queue-name orders
AWS_ACCESS_KEY_ID=222222222222 aws sqs create-queue --queue-name orders
任何其他格式的密钥,例如 test 或 AKIA...,会使 Floci 回退到 FLOCI_DEFAULT_ACCOUNT_ID,其默认值为 000000000000。
STS 临时凭据也会被路由:来自 AssumeRole 的凭据会解析为所代入角色的账号,因此跨账号的“先 assume-role 再预置资源”模式可以在本地工作。解析优先级为:12 位 AKID → 临时会话查找 → FLOCI_DEFAULT_ACCOUNT_ID。
参见《多账号隔离》文档。
SDK 集成#
将你现有的 AWS SDK 指向 http://localhost:4566。
Java,AWS SDK v2#
var client = DynamoDbClient.builder()
.endpointOverride(URI.create("http://localhost:4566"))
.region(Region.US_EAST_1)
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create("test", "test")))
.build();
client.createTable(b -> b
.tableName("demo-table")
.billingMode(BillingMode.PAY_PER_REQUEST)
.attributeDefinitions(
AttributeDefinition.builder().attributeName("pk").attributeType(ScalarAttributeType.S).build())
.keySchema(
KeySchemaElement.builder().attributeName("pk").keyType(KeyType.HASH).build()));
System.out.println(client.listTables().tableNames());
Python,boto3#
import boto3
client = boto3.client(
"ssm",
endpoint_url="http://localhost:4566",
region_name="us-east-1",
aws_access_key_id="test",
aws_secret_access_key="test",
)
client.put_parameter(
Name="/demo/app/message",
Value="hello from floci",
Type="String",
Overwrite=True,
)
response = client.get_parameter(Name="/demo/app/message")
print(response["Parameter"]["Value"])
Node.js,AWS SDK v3#
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
const client = new SQSClient({
endpoint: "http://localhost:4566",
region: "us-east-1",
credentials: { accessKeyId: "test", secretAccessKey: "test" },
});
await client.send(
new SendMessageCommand({
QueueUrl: "http://localhost:4566/000000000000/demo-queue",
MessageBody: "hello from floci",
}),
);
Go,AWS SDK v2#
package main
import (
"context"
"fmt"
"log"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
cfg, err := config.LoadDefaultConfig(context.TODO(),
config.WithRegion("us-east-1"),
config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider("test", "test", ""),
),
config.WithBaseEndpoint("http://localhost:4566"),
)
if err != nil {
log.Fatal(err)
}
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.UsePathStyle = true
})
out, err := client.ListBuckets(context.TODO(), nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(out.Buckets)
}
Rust,AWS SDK#
use aws_sdk_secretsmanager::config::{Credentials, Region};
use aws_sdk_secretsmanager::Client;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = aws_config::defaults(aws_config::BehaviorVersion::latest())
.region(Region::new("us-east-1"))
.credentials_provider(Credentials::new("test", "test", None, None, "floci"))
.endpoint_url("http://localhost:4566")
.load()
.await;
let client = Client::new(&config);
client
.create_secret()
.name("demo/secret")
.secret_string("hello from floci")
.send()
.await?;
Ok(())
}
Bash,AWS CLI#
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_DEFAULT_REGION=us-east-1
aws --endpoint-url http://localhost:4566 s3 mb s3://my-bucket
aws --endpoint-url http://localhost:4566 s3 ls
Testcontainers#
Floci 提供 Testcontainers 模块,可直接从测试中启动隔离的 Floci 实例。这避免了共享状态、手动守护进程设置和端口冲突。
对于 Testcontainers 1.x,请使用下表所示的版本。
| 语言 | 包 | 最新版本 | 仓库 | 源码 |
|---|---|---|---|---|
| Java | io.floci:testcontainers-floci | 1.14.0 | Maven Central | GitHub |
| Node.js | @floci/testcontainers | 0.1.0 | npm | GitHub |
| Python | testcontainers-floci | 0.1.1 | PyPI | GitHub |
| .NET | Testcontainers.Floci | 见 releases | GitHub Packages | GitHub |
| Go | 进行中 | 进行中 | N/A | GitHub |
Java#
<dependency>
<groupId>io.floci</groupId>
<artifactId>testcontainers-floci</artifactId>
<version>1.14.0</version>
<scope>test</scope>
</dependency>
@Testcontainers
class S3IntegrationTest {
@Container
static FlociContainer floci = new FlociContainer();
@Test
void shouldCreateBucket() {
S3Client s3 = S3Client.builder()
.endpointOverride(URI.create(floci.getEndpoint()))
.region(Region.of(floci.getRegion()))
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(floci.getAccessKey(), floci.getSecretKey())))
.forcePathStyle(true)
.build();
s3.createBucket(b -> b.bucket("my-bucket"));
}
}
对于 Testcontainers 2.x / Spring Boot 4.x,请使用版本 2.15.0。
Node.js / TypeScript#
npm install --save-dev @floci/testcontainers
import { FlociContainer } from "@floci/testcontainers";
import { S3Client, CreateBucketCommand } from "@aws-sdk/client-s3";
describe("S3", () => {
let floci: FlociContainer;
beforeAll(async () => {
floci = await new FlociContainer().start();
});
afterAll(async () => {
await floci.stop();
});
it("creates a bucket", async () => {
const s3 = new S3Client({
endpoint: floci.getEndpoint(),
region: floci.getRegion(),
credentials: {
accessKeyId: floci.getAccessKey(),
secretAccessKey: floci.getSecretKey(),
},
forcePathStyle: true,
});
await s3.send(new CreateBucketCommand({ Bucket: "my-bucket" }));
});
});
Python#
pip install testcontainers-floci
import boto3
from floci import FlociContainer
def test_s3_create_bucket():
with FlociContainer() as floci:
s3 = boto3.client(
"s3",
endpoint_url=floci.get_endpoint(),
region_name=floci.get_region(),
aws_access_key_id=floci.get_access_key(),
aws_secret_access_key=floci.get_secret_key(),
)
s3.create_bucket(Bucket="my-bucket")
兼容性测试#
compatibility-tests 目录跨 SDK 和工具工作流验证 Floci。
| 模块 | 语言 / 工具 | SDK / 客户端 | 测试数 |
|---|---|---|---|
| sdk-test-java | Java 17 | AWS SDK for Java v2 | 1,326 |
| sdk-test-node | Node.js | AWS SDK for JavaScript v3 | 449 |
| sdk-test-python | Python 3 | boto3 | 311 |
| sdk-test-go | Go | AWS SDK for Go v2 + RDS Data API SDK v1 | 157 |
| sdk-test-awscli | Bash | AWS CLI v2 | 205 |
| compat-terraform | Terraform | v1.10+ | 67 |
| compat-opentofu | OpenTofu | v1.9+ | 41 |
| compat-cdk | AWS CDK | v2+ | 20 |
5 个 SDK 和 3 个 IaC 工具共 2,576 个自动化兼容性测试。
从 LocalStack 迁移#
Floci 是 LocalStack 社区版的可直接替换方案。端口、凭据、SDK 配置和 CLI 端点模式的工作方式相同。替换镜像即可继续。
# 之前
image: localstack/localstack
# 之后,标准镜像
image: floci/floci:latest
# 之后,如果初始化脚本需要 AWS CLI 或 boto3
image: floci/floci:latest-compat
LocalStack 环境变量会自动转换:
| LocalStack | Floci 对应项 |
|---|---|
| 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 |
挂载在 /etc/localstack/init/ 下的初始化脚本可原样运行。/_localstack/init 和 /_localstack/health 端点仍会提供。模拟器启动后,日志还会以 LocalStack 风格的 Ready. 行结尾,因此依赖监听该日志行的工具(例如 Testcontainers 的 LocalStackContainer 默认等待策略)可原样工作。设置 LOCALSTACK_PARITY=false 可关闭自动转换。
参见完整迁移指南。
镜像标签#
每个标签由变体(variant)和通道(channel)组合而成。
| 通道 | 标准 | 基线(仅 ARM64) | 含 AWS CLI 和 boto3 的 compat |
|---|---|---|---|
| 发行版,浮动 | latest | latest-baseline | latest-compat |
| 发行版,固定版本 | x.y.z | x.y.z-baseline | x.y.z-compat |
| Nightly,浮动 | nightly | — | nightly-compat |
| Nightly,按日期 | nightly-mmddyyyy | — | nightly-mmddyyyy-compat |
稳定发行版使用 latest,可复现构建使用固定版本,跟踪 main 使用 nightly。
# 推荐
image: floci/floci:latest
# 包含 AWS CLI 和 boto3
image: floci/floci:latest-compat
# 适用于 Raspberry Pi 4 / 早期 LSE 核心的 ARM64 基线
image: floci/floci:latest-baseline
# 固定发行版
image: floci/floci:x.y.z
# 跟踪 main
image: floci/floci:nightly
发布节奏#
稳定版本在每月 15 日和最后一天发布,于美国中部时间 00:30 自动切出。两次发布之间,floci/floci:nightly 跟踪 main。每个合并的修复次日即可用,带日期的 nightly-mmddyyyy 标签可让你固定某个夜晚的构建。
版本由 semantic-release 从 Conventional Commits 推导;CHANGELOG.md 为自动生成,从不手工编辑。发行版仅从 main 切出:没有维护分支。
配置#
所有设置都可以通过带 FLOCI_ 前缀的环境变量覆盖。
| 变量 | 默认值 | 说明 |
|---|---|---|
| FLOCI_PORT | 4566 | Floci API 暴露的端口 |
| FLOCI_DEFAULT_REGION | us-east-1 | 默认 AWS 区域 |
| FLOCI_DEFAULT_ACCOUNT_ID | 000000000000 | 默认 AWS 账号 ID |
| FLOCI_BASE_URL | http://localhost:4566 | Floci 返回服务 URL 时使用的基础 URL |
| FLOCI_HOSTNAME | 未设置 | 当 Floci 运行在 Docker Compose 内时,返回 URL 中使用的主机名 |
| FLOCI_STORAGE_MODE | memory | 存储模式:memory、persistent、hybrid 或 wal |
| FLOCI_STORAGE_PERSISTENT_PATH | ./data | 用于持久化状态的目录 |
| FLOCI_SERVICES_LAMBDA_ECR_BASE_URI | public.ecr.aws | 拉取 Lambda 运行时镜像时使用的 ECR 基础 URI(旧名称 FLOCI_ECR_BASE_URI 仍然有效) |
| FLOCI_SERVICES_S3_ENFORCE_AUTH | false | 强制执行 S3 公共/私有读取访问,并拒绝未知的已签名 S3 访问密钥 |
完整参考:配置文档
多容器 Docker Compose#
当你的应用运行在另一个容器中时,将 FLOCI_HOSTNAME 设置为 Floci 的服务名,以便返回的 URL(例如 SQS 的 QueueUrl 值)能够正确解析。
services:
floci:
image: floci/floci:latest
ports:
- "4566:4566"
environment:
- FLOCI_HOSTNAME=floci
my-app:
environment:
- AWS_ENDPOINT_URL=http://floci:4566
depends_on:
- floci
否则,服务可能返回使用 localhost 的 URL,从应用容器看过去会指向错误的容器。
社区#
在 Slack 或 GitHub Discussions 加入 Floci 社区。欢迎功能想法、兼容性问题、设计取舍以及初步提案。
赞助商#
Floci 是独立的开源项目,由使用它的人和公司资助。 赞助只换来感谢,别无其他:每个模拟服务对所有人永久免费,没有赞助商能获得 其他 Flock 成员没有的功能、优先级或路线图影响力。
🥇 金牌
在模拟器 README 和 floci.io 上放置大号 logo 并置于顶部位置,同时在发行说明中提及。
IceGuard · Softmax
🥈 银牌
在模拟器 README 和 floci.io 上放置 logo,同时在发行说明中提及。
这里放你的 logo。成为赞助商。
🥉 社区
在模拟器 README 中列出名称、GitHub 上的赞助商徽章,以及我们诚挚的感谢。
AutoScout24 · Nexxion AI
每位赞助商,包括在这些层级之外支持 Floci 的“Friends of the Flock”,都列在 THANKS.md 中。
赞助 Floci
星标历史#
贡献者#
许可证#
MIT。随便你怎么用。