flox-environments

flox-environments

热门

使用 Flox 打造可复现、跨平台(macOS/Linux)的开发环境。Flox 是一款基于 Nix 的声明式环境管理工具。适用于为任意语言搭建项目工具链、安装系统级依赖(编译器、数据库、openssl/BLAS 等底层原生库)、锁定团队统一的软件包版本、运行本地服务(PostgreSQL、Redis、Kafka)、一键完成新成员入职环境配置,或解决“在我电脑上明明能跑”的经典坑——也包括不需要 sudo 权限就能在项目作用域下安装所需工具的 AI Agent / vibe coding 场景。当用户提及 .flox/、manifest.toml、flox activate 或 FloxHub 时同样适用。

24万Star
3.6万Fork
更新于 2026/8/3
SKILL.md
只读
名称
flox-environments
描述

使用 Flox 打造可复现、跨平台(macOS/Linux)的开发环境。Flox 是一款基于 Nix 的声明式环境管理工具。适用于为任意语言搭建项目工具链、安装系统级依赖(编译器、数据库、openssl/BLAS 等底层原生库)、锁定团队统一的软件包版本、运行本地服务(PostgreSQL、Redis、Kafka)、一键完成新成员入职环境配置,或解决“在我电脑上明明能跑”的经典坑——也包括不需要 sudo 权限就能在项目作用域下安装所需工具的 AI Agent / vibe coding 场景。当用户提及 .flox/、manifest.toml、flox activate 或 FloxHub 时同样适用。

Flox Environments

Flox 可以通过单个 TOML 清单文件定义并创建可复现的开发环境。无需依赖容器或虚拟机,团队中的每位成员都能在 macOS 和 Linux 上获得完全一致的软件包、工具和配置。基于 Nix 打造,可直接调配超过 150,000 个软件包。

什么时候激活/使用

当用户遇到环境管理相关的问题时,即可使用此 Skill——即便他们未主动提及 Flox。在以下场景中,Flox 是最佳选择:

  • 项目除了语言本身的依赖外,还需要系统级软件包(编译器、数据库、CLI 工具)
  • 重视可复现性——配置需在队友机器、CI 环境或新电脑上保持完全一致的运行结果
  • 需要多种工具共存——例如在同一个环境中同时使用 Python 3.11 + PostgreSQL 16 + Redis + Node.js
  • 需要跨平台支持(同一套配置同时兼容 macOS 与 Linux)
  • AI Agent 需要安装工具——Flox 允许 Agent 在无需 sudo 权限、不污染全局环境、不受沙箱限制的前提下,向项目作用域的环境中添加软件包

如果用户只需要单一语言的运行时且无系统级依赖,使用标准工具(如单用 nvm、pyenv、rustup)就足够了。如果需要完全的 OS 级隔离,容器可能更合适。Flox 则恰好踩在黄金平衡点上:既有声明式、可复现的环境能力,又没有容器带来的额外资源开销。

前置条件: 需先安装 Flox——macOS、Linux 及 Docker 的安装步骤请参考 flox.dev/docs

核心概念

Flox 环境定义在 .flox/env/manifest.toml 中,并通过 flox activate 激活。清单中声明了软件包、环境变量、初始化 hook 和 Shell 配置——即在任何地方复现该环境所需的一切。

关键路径:

  • .flox/env/manifest.toml — 环境定义文件(需提交至 Git)
  • $FLOX_ENV — 已安装软件包的运行时路径(类似于 /usr,包含 bin/lib/include/
  • $FLOX_ENV_CACHE — 用于存储缓存、虚拟环境 (venv)、数据的本地持久化存储目录(在重新构建后依然保留)
  • $FLOX_ENV_PROJECT — 项目根目录(即 .flox/ 所在的路径)

常用命令

flox init                       # 创建新环境
flox search <package> [--all]   # 搜索软件包
flox show <package>             # 查看可选版本
flox install <package>          # 添加软件包
flox list                       # 列出已安装的软件包
flox activate                   # 进入环境
flox activate -- <cmd>          # 在环境中运行命令(不启动子 shell)
flox edit                       # 交互式编辑配置清单

清单文件结构

# .flox/env/manifest.toml

[install]
# 需要安装的软件包——环境的核心部分
ripgrep.pkg-path = "ripgrep"
jq.pkg-path = "jq"

[vars]
# 静态环境变量
DATABASE_URL = "postgres://localhost:5432/myapp"

[hook]
# 非交互式初始化脚本(每次激活时自动运行)
on-activate = """
  echo "Environment ready"
"""

[profile]
# Shell 函数和别名(仅在交互式 Shell 中生效)
common = """
  alias dev="npm run dev"
"""

[options]
# 支持的系统平台
systems = ["x86_64-linux", "aarch64-linux", "x86_64-darwin", "aarch64-darwin"]

软件包安装范式

基础安装

[install]
nodejs.pkg-path = "nodejs"
python.pkg-path = "python311"
rustup.pkg-path = "rustup"

锁定具体版本

[install]
nodejs.pkg-path = "nodejs"
nodejs.version = "^20.0"          # Semver 版本范围:最新的 20.x

postgres.pkg-path = "postgresql"
postgres.version = "16.2"         # 精确版本

平台专属软件包

[install]
# 仅 Linux 用的工具
valgrind.pkg-path = "valgrind"
valgrind.systems = ["x86_64-linux", "aarch64-linux"]

# macOS 原生 Framework
Security.pkg-path = "darwin.apple_sdk.frameworks.Security"
Security.systems = ["x86_64-darwin", "aarch64-darwin"]

# macOS 上的 GNU 工具链(解决与 BSD 默认命令行为不一致的问题)
coreutils.pkg-path = "coreutils"
coreutils.systems = ["x86_64-darwin", "aarch64-darwin"]

解决软件包冲突

当两个软件包安装了同名二进制文件时,可通过 priority 指定优先级(数值越小优先级越高):

[install]
gcc.pkg-path = "gcc12"
gcc.priority = 3

clang.pkg-path = "clang_18"
clang.priority = 5               # 文件冲突时 gcc 优先

使用 pkg-group 对需要一同进行版本解析的软件包进行分组:

[install]
python.pkg-path = "python311"
python.pkg-group = "python-stack"

pip.pkg-path = "python311Packages.pip"
pip.pkg-group = "python-stack"    # 与 python 一起解析版本

针对各语言的具体配置方案

Python + uv

[install]
python.pkg-path = "python311"
uv.pkg-path = "uv"

[vars]
UV_CACHE_DIR = "$FLOX_ENV_CACHE/uv-cache"
PIP_CACHE_DIR = "$FLOX_ENV_CACHE/pip-cache"

[hook]
on-activate = """
  venv="$FLOX_ENV_CACHE/venv"
  if [ ! -d "$venv" ]; then
    uv venv "$venv" --python python3
  fi
  if [ -f "$venv/bin/activate" ]; then
    source "$venv/bin/activate"
  fi

  if [ -f requirements.txt ] && [ ! -f "$FLOX_ENV_CACHE/.deps_installed" ]; then
    uv pip install --python "$venv/bin/python" -r requirements.txt --quiet
    touch "$FLOX_ENV_CACHE/.deps_installed"
  fi
"""

Node.js

[install]
nodejs.pkg-path = "nodejs"
nodejs.version = "^20.0"

[hook]
on-activate = """
  if [ -f package.json ] && [ ! -d node_modules ]; then
    npm install --silent
  fi
"""

Rust

[install]
rustup.pkg-path = "rustup"
pkg-config.pkg-path = "pkg-config"
openssl.pkg-path = "openssl"

[vars]
RUSTUP_HOME = "$FLOX_ENV_CACHE/rustup"
CARGO_HOME = "$FLOX_ENV_CACHE/cargo"

[profile]
common = """
  export PATH="$CARGO_HOME/bin:$PATH"
"""

Go

[install]
go.pkg-path = "go"
gopls.pkg-path = "gopls"
delve.pkg-path = "delve"

[vars]
GOPATH = "$FLOX_ENV_CACHE/go"
GOBIN = "$FLOX_ENV_CACHE/go/bin"

[profile]
common = """
  export PATH="$GOBIN:$PATH"
"""

C/C++

[install]
gcc.pkg-path = "gcc13"
gcc.pkg-group = "compilers"

# 注意:单独安装 gcc 不会自动提供 libstdc++ 头文件——还需要指定 gcc-unwrapped
gcc-unwrapped.pkg-path = "gcc-unwrapped"
gcc-unwrapped.pkg-group = "libraries"

cmake.pkg-path = "cmake"
cmake.pkg-group = "build"

gnumake.pkg-path = "gnumake"
gnumake.pkg-group = "build"

gdb.pkg-path = "gdb"
gdb.systems = ["x86_64-linux", "aarch64-linux"]

Hook 机制与 Profile 配置

Hooks — 非交互式初始化

每次环境激活时都会执行 Hook。应确保其执行速度够快且具备幂等性。经验法则:如果需要自动静默触发,放到 [hook];如果需要由用户手动敲命令触发,放到 [profile]

[hook]
on-activate = """
  setup_database() {
    if [ ! -d "$FLOX_ENV_CACHE/pgdata" ]; then
      initdb -D "$FLOX_ENV_CACHE/pgdata" --no-locale --encoding=UTF8
    fi
  }
  setup_database
"""

Profile — 交互式 Shell 配置

Profile 中的代码会在用户的当前 Shell 会话中生效。

[profile]
common = """
  dev() { npm run dev; }
  test() { npm run test -- "$@"; }
"""

避坑指南

使用绝对路径

# 错误做法 — 在其他机器上容易跑不通
[vars]
PROJECT_DIR = "/home/alice/projects/myapp"

# 正确做法 — 使用 Flox 内置环境变量
[vars]
PROJECT_DIR = "$FLOX_ENV_PROJECT"

在 Hook 中直接使用 exit

# 错误做法 — 会直接终止退出当前的 Shell 进程
[hook]
on-activate = """
  if [ ! -f config.json ]; then
    echo "Missing config"
    exit 1
  fi
"""

# 正确做法 — 使用 return 跳出 Hook 脚本,不要用 exit
[hook]
on-activate = """
  if [ ! -f config.json ]; then
    echo "Missing config — run setup first"
    return 1
  fi
"""

在配置清单中明文硬编码敏感信息

# 错误做法 — manifest 会被提交进 Git 仓库
[vars]
API_KEY = "<set-at-runtime>"

# 正确做法 — 读取外部环境变量或在运行时注入
# 运行方式:API_KEY="<your-api-key>" flox activate
[vars]
API_KEY = "${API_KEY:-}"

Hook 耗时过长且缺乏防重复执行校验

# 错误做法 — 每次激活环境都会重复执行全量安装
[hook]
on-activate = """
  pip install -r requirements.txt
"""

# 正确做法 — 如果检测到已安装则跳过
[hook]
on-activate = """
  if [ ! -f "$FLOX_ENV_CACHE/.deps_installed" ]; then
    uv pip install -r requirements.txt --quiet
    touch "$FLOX_ENV_CACHE/.deps_installed"
  fi
"""

在 Hook 中放置用户交互命令

# 错误做法 — 在 hook 中定义的函数无法直接在交互式 shell 里调用
[hook]
on-activate = """
  deploy() { kubectl apply -f k8s/; }
"""

# 正确做法 — 用户可手动调用的函数请写在 [profile] 中
[profile]
common = """
  deploy() { kubectl apply -f k8s/; }
"""

全栈项目实战示例

一个包含 PostgreSQL 服务的 Python API 完整开发环境配置:

[install]
python.pkg-path = "python311"
uv.pkg-path = "uv"
postgresql.pkg-path = "postgresql_16"
redis.pkg-path = "redis"
jq.pkg-path = "jq"
curl.pkg-path = "curl"

[vars]
UV_CACHE_DIR = "$FLOX_ENV_CACHE/uv-cache"
DATABASE_URL = "postgres://localhost:5432/myapp"
REDIS_URL = "redis://localhost:6379"

[hook]
on-activate = """
  if [ ! -d "$FLOX_ENV_CACHE/pgdata" ]; then
    initdb -D "$FLOX_ENV_CACHE/pgdata" --no-locale --encoding=UTF8
  fi

  venv="$FLOX_ENV_CACHE/venv"
  if [ ! -d "$venv" ]; then
    uv venv "$venv" --python python3
  fi
  if [ -f "$venv/bin/activate" ]; then
    source "$venv/bin/activate"
  fi

  if [ -f requirements.txt ] && [ ! -f "$FLOX_ENV_CACHE/.deps_installed" ]; then
    uv pip install --python "$venv/bin/python" -r requirements.txt --quiet
    touch "$FLOX_ENV_CACHE/.deps_installed"
  fi
"""

[profile]
common = """
  serve() { uvicorn app.main:app --reload --host 0.0.0.0 --port 8000; }
  migrate() { alembic upgrade head; }
"""

[services]
postgres.command = "postgres -D $FLOX_ENV_CACHE/pgdata -k $FLOX_ENV_CACHE"
redis.command = "redis-server --port 6379 --daemonize no"

[options]
systems = ["x86_64-linux", "aarch64-linux", "x86_64-darwin", "aarch64-darwin"]

带服务一起激活环境:flox activate --start-services

环境共享与分发

Flox 环境是 Git 原生的。只需把 .flox/ 目录提交到 Git,团队里的每一位协同开发者就能获取完全一致的环境:

git add .flox/
git commit -m "Add Flox environment"
# 队友只需执行:
git clone <repo> && cd <repo> && flox activate

如果要跨项目复用基础环境,可以推送到 FloxHub:

flox push                         # 推送环境到 FloxHub
flox activate -r owner/env-name   # 在任何地方激活远端环境

使用 [include] 组合多个环境配置:

[include]
base.floxhub = "myorg/python-base"

[install]
# 在基础环境之上的项目专属新增依赖
fastapi.pkg-path = "python311Packages.fastapi"

AI 辅助与 Vibe Coding 场景支持

Flox 是 AI 辅助开发和 vibe coding 工作流的绝佳搭配。当 AI Agent 需要当前环境缺失的工具(如编译器、数据库、Linter 或某个 CLI 小工具)时,可以直接把它写入项目级的 Flox 清单中,而无需获取 sudo 权限、不会污染系统全局环境,更不会被沙箱安全限制卡住。

为什么这对 Agent 至关重要:

  • 无需 sudo 权限flox install 完全运行在用户空间,Agent 可以在没有高权限的情况下自由安装工具
  • 项目级作用域隔离 — 软件包仅安装在当前项目环境内而非全局,不同项目使用不同版本的依赖也不会产生冲突
  • 对沙箱环境友好 — 即便 Agent 运行在受到限制或沙箱化的环境中,依然能够顺畅安装所需的工具