floci 实测:LocalStack 停摆后的免费 AWS 模拟器,我无 Docker 从源码跑通了 Agent 本地云链路

LocalStack 社区版今年 3 月起强制要求登录令牌,本地 AWS 模拟这个赛道就被腾出了一半。三个月过去,接棒者是今年 2 月才创建的 floci——MIT 协议、单日新增近 700 star、GitHub 上 28,790 颗星(11 月 4 日数据)。它打动我的不只是免费:官方页面上明晃晃写着「Built for AI-assisted development」,主张给编码 Agent 一个「跑不坏的本地云」。

这正好和本站最近测的 AI Agent 基础设施是一路的:Lightpanda 解决 Agent 看网页,floci 解决 Agent 摸云。所以我没只当它是 DevOps 工具来测——这篇会回答三个问题:16GB Mac 上怎么把它跑起来(剧透:官方说的独立二进制根本不存在)、核心服务到底能不能真用、以及让一个免费 AI 模型在它上面真建一个桶要多久。

一、先泼冷水:官方文档的三条路,两条半走不通

官方安装文档给了三条路:Docker 镜像、独立二进制、源码构建。我的 M4(16GB,macOS 26.5.2)上没有 Docker,于是自然转向第二条——文档说「每个 release 都附带各平台的独立二进制」,资产名都列好了(floci-aws-darwin-arm64)。

实际去 GitHub release 页面:2.4.0 的资产列表是空的,直接拼下载链接返回 404。我用 API 查了最近五个 release,assets 全部为 0。文档超前于现实,这一点后续可能修复,但至少 11 月 4 日当天,无 Docker 用户只剩源码构建一条路。

顺带排除一个误解:官方那个 floci 命令行工具(floci-cli)不是模拟器本体,它只是 Docker 容器的启停管理器——floci start 干的事是拉镜像、起容器。没有 Docker,装它没有意义。

源码构建前还要过一个坑:仓库用 Maven enforcer 把 JDK 锁死在 [25,26) 区间,我先用 brew 装的最新 OpenJDK 27 直接被拒(报错信息倒是写得明白:「Floci requires JDK 25」)。装 openjdk@25 后:

Bash
# 环境:macOS 26.5.2 / M4 16GB / openjdk@25 (brew) / Maven 3.10
brew install openjdk@25 maven
export JAVA_HOME=/opt/homebrew/Cellar/openjdk@25/25.0.5.0.3/libexec/openjdk.jdk/Contents/Home

git clone --depth 1 https://github.com/floci-io/floci.git
cd floci
mvn clean package -DskipTests   # 依赖预热后 59 秒编译完成(M4 实测)
java -jar target/quarkus-app/quarkus-run.jar

启动后我用健康检查计时:从进程拉起到 /_localstack/health 返回 200,2.14 秒。进程常驻内存 330MB。这两个数字是 JVM 模式跑出来的——官方宣称的 24ms 启动、13MiB 内存属于 GraalVM 原生二进制,本机装不上(见上),只能如实记录差距。

倒是启动日志让我对它的工程态度加了分:检测不到 Docker 时,它打印一份完整清单,明说哪些服务只保留控制面(RDS、ElastiCache、Neptune 等 10 个)、哪些服务的哪些操作会直接失败(Lambda、ECS、CodeBuild 等 16 个),和文档逐字对得上。不糊弄,失败了也知道为什么。

二、核心服务实测:全通,而且 Lambda 的失败方式值得表扬

凭据随手填、端点指到 4566,标准 AWS CLI 流程原样跑。下面这段可以直接复制(我用的 awscli 1.46.2,Python 虚拟环境里 pip install awscli):

Bash
export AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test AWS_DEFAULT_REGION=us-east-1
EP=http://127.0.0.1:4566

aws --endpoint-url $EP sts get-caller-identity        # 返回 root,账号 000000000000
aws --endpoint-url $EP s3 mb s3://apisit-test-bucket  # 建桶
aws --endpoint-url $EP s3 cp hello.txt s3://apisit-test-bucket/
aws --endpoint-url $EP dynamodb create-table --table-name orders \
  --attribute-definitions AttributeName=id,AttributeType=S \
  --key-schema AttributeName=id,KeyType=HASH --billing-mode PAY_PER_REQUEST
aws --endpoint-url $EP secretsmanager create-secret \
  --name prod/db --secret-string '{"user":"admin","pass":"s3cr3t"}'

S3、DynamoDB、SQS、Secrets Manager、STS、IAM 全部按真实 AWS 的返回结构工作。更值得看的是跨服务事件流——EventBridge 规则投递到 SQS 队列,put-events 之后两秒,队列里收到的消息是完整的事件信封:version、id、detail-type、account、time、region、event-bus-name 一个字段不缺。serverless 架构里最核心的「事件在服务间真实流转」,本地闭环成立。

然后是我认为本次实测里最漂亮的细节:Lambda。没有 Docker 的情况下,create-function 照样成功(控制面在),但 invoke 时它没有假装执行成功,而是返回 FunctionError: "Unhandled",错误消息直说「Failed to start Lambda container: Docker is not reachable. Lambda functions run in Docker containers.」——HTTP 状态码 200,函数错误独立标注。对比某些模拟器mock到底、返回一个假的成功响应,这种「失败得诚实」才是集成测试真正需要的语义。

三、一个差点打到真云的坑

测 SQS 时我遇到了本次最大的意外:同样用 test/test 凭据,boto3 一路绿灯,AWS CLI 却连续报 InvalidClientTokenId——「The security token included in the request is invalid」。我一度以为是 floci 对 SQS 做了更严的签名校验,翻源码翻到一半才反应过来:AWS CLI v1 根本不认识 AWS_ENDPOINT_URL 这个环境变量,我的 SQS 请求从头到尾发往的是真实的 sqs.us-east-1.amazonaws.com,是真正的 AWS 在拒绝 test 凭据。

这个坑值得单独写出来,因为它有两层教训。第一,本地模拟场景里 CLI 要么升到 v2,要么每次显式带 --endpoint-url。第二层更重要:当你对着模拟器干活却收到 InvalidClientTokenId,先别怀疑模拟器——这可能说明你的请求压根没进模拟器,而是发去了真云。反过来的场景更吓人:如果那时本地环境里配的是真实凭据,这些请求就真到云上了。写 CI 脚本时把端点校验做在前面,比事后查账单划算得多。

第二个坑小一些但也说明问题:文档说持久化模式的状态存放在 macOS 的 ~/Library/Application Support/floci-aws,JVM 模式实跑下来落在工作目录的 ./data(每个服务一个 JSON 文件,全量 860KB)。持久化本身是真实可用的——我开了 FLOCI_STORAGE_MODE=persistent 后建桶写入,杀进程重启,桶和对象原样回来。只是别按文档路径去找你的状态。

四、Agent 实测:免费模型 45 秒在本地云上真建了一个桶

这轮测试的主菜:让一个 AI Agent 直接操作 floci。环境是 OpenCode 2.1.4 加免费档的 glm-5.3-flash-free(零成本;顺带一提模型前缀要用 opencode/,写 openrouter/ 会报 Model unavailable)。任务四步:建桶、上传 notes.txt、列对象、读回内容。

结果:44.8 秒全部完成,全程 15,200 input / 1,254 output token,花费 $0。中途它还自己纠了一次错——第一次 get-object 把输出重定向到了 /dev/null,命令实际成功了但没读到内容,它意识到后重新下载到临时文件再读。任务结束后我从旁边用独立的 AWS CLI 会话核验:桶 agent-bucket-1104 真实存在,notes.txt 内容一字不差。

这正是官方那套「Zero blast radius」叙事的实证:Agent 再怎么折腾,最坏结果是重置一个本地进程;凭据 test/test 泄露了也无所谓;账单恒为零。给编码 Agent 配云工具时,把 endpoint 指向 floci 而不是真实账号,是目前我见过风险最低的接法。配合 TokenEconomizer 这类省钱插件,本地推理加本地云,Agent 工作流的两大成本项都能压到零——后者此前在 colibri 那篇里已经有讨论,这里不展开。

五、这几个场景我建议你别用

实测下来它的边界同样清楚,三类场景不推荐:

容器型服务的真实行为验证。 没有配套 Docker 时,Lambda、RDS、ECS、CodeBuild 这些只有控制面外壳,数据面要么空转要么直接拒绝。就算配了 Docker,它跑的也是你本机的容器——Lambda 冷启动时长、RDS 参数组调优这类「贴近生产」的验证,本地模拟永远给不出答案。

安全与权限类测试。 任意非空凭据都能通过,IAM 策略评估默认关闭。它模拟的是 AWS 的接口形态,不是安全边界,拿它测「这个策略到底拦不拦得住」会得到彻底失真的结论。

性能基准。 24ms 对 3.3 秒的启动差是原生二进制对 JVM 容器的比较,本机 JVM 模式实测 2.1 秒依然比 LocalStack 快,但「快 138 倍」这种数字换个环境就是另一个量级。延迟、吞吐类指标与真云的全球网络拓扑无关,参考意义有限。

写在最后

floci 的出现时机几乎是完美的:LocalStack 收紧的那天,AI Agent 正好开始大规模伸手要云环境。前者把开发者推向替代品,后者给了替代品一个比「省 CI 时间」性感得多的理由。从源码质量看——错误消息的精确程度、失败模式的诚实度、133 个服务各一页的文档——这不是蹭热点的项目,是认真在接盘的。

给想上手的人一个最短路径:有 Docker 直接拉 floci/floci:latest(90MB,比 LocalStack 镜像小一个量级);没有 Docker 就走本文的源码路线,记得锁 JDK 25。独立二进制等官方把 release 资产补上再说,截至目前它还停留在文档里。

推荐阅读

  • colibri 实测:大模型不装内存、改「摆放」,我在 16GB M4 上摸清了它的真实边界

    GitHub 46,000 star 的纯 C 推理引擎 colibri,把 744B 大模型的专家权重留在磁盘、按 token 流式读取。我在 16GB M4 Mac 上实测:规划器裁决显示内存下限…

  • Lightpanda 实测:给 AI Agent 换个不吃内存的无头浏览器,我在 M4 上和 Chrome 真刀真枪比了一轮

    GitHub 4 万 star 的 Zig 无头浏览器 Lightpanda,专为 AI Agent 抓网页而生。我在 16GB M4 Mac 上实测:与 Chrome headless 同页对比,峰…

  • unslop 实测:用免费模型把「一眼 AI 生成」的界面改成有设计感的页面

    GitHub 三天 3500+ star 的 unslop 技能,专治 AI 生成界面的紫渐变、发光、emoji 图标和乱间距。我用 opencode 加免费模型真实跑了一遍:从安装、造重 slop …

  • TokenEconomizer 实测:微软开源的编码 Agent 省钱插件,我在 opencode 上跑通了仓库手册注入,也踩了三个坑

    微软研究院开源的 TokenEconomizer 给编码 Agent 加了经验复用层:从历史会话蒸馏仓库事实,下个会话开头直接注入。我在 opencode 上做了 15 个会话对照实测:token 变…