最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
ubuntu-bootstrap:实践指南
时间:2026-10-02 20:46:01 编辑:袖梨 来源:一聚教程网
实际看ubuntu-bootstrap,先要确认它的用途:Ubuntu 26.04 LTS 工作站引导程序与 Fluxion:apt/Docker/toolchains/flatpaks/GNOME。部署与运行环境里,权限、依赖和环境差异会放大维护成本。我会在非生产环境复现一次安装与运行,检查依赖锁定、权限边界、日志、回滚和资源消耗。它适合愿意维护环境并重视故障恢复的工程团队;采用前仍要看维护状态和试跑结果。

ubuntu 引导程序
此存储库使用 Ubuntu 26.04 LTS (“resolute”,GNOME 50,amd64)设置我的工作站 Fluxion 0.4.1 或更高版本(请参阅 Fluxion 版本)。
它移植了 Arch 和 Fedora 脚本 w0rxbend/system-bootstrap 到声明性通量配置文件。它还 重现了我在之前的工作站安装中手动安装的所有内容,如 bash 和 zsh 历史记录中所示, apt log, and the snap and flatpak lists. The same tools stay in charge of their own jobs:
- dotbot (dotbot-go) 直接从原始存储库的实时克隆链接点文件
~/.system-bootstrap(没有任何内容复制到此存储库中)。 - nerd-fonts-installer 安装 Nerd 字体。
- cargo-binstall 安装 Rust CLI 工具。
- binstaller 将固定版本二进制文件安装在
~/.apps中。 - SDKMAN、nvm、pyenv 和其他语言安装程序的工作方式与以前一样。
桌面是 Ubuntu 自己的 GNOME 会话(Ubuntu Dock、Yaru),带有 Fedora 风格的 Super+1..9 工作区和 Vicinae 启动器
Super+D。不包括平铺或 Arch 桌面设置中的任何内容(niri、DMS、sway、PaperWM、waybar 等),
Docker CE 取代了 podman。代理技能位于每个编码代理都链接到的一个 git-tracked 文件夹中。
测试工具在生成的、不间断的配置文件副本上运行相同的编排。
内容
- 快速入门
- 首先在全新的Ubuntu上运行,一步一步
- Fluxion版本
- 工作原理
- 布局
- 模块
- 库存充足
- Docker 代替 podman
- 带有 dotbot 的 Dotfiles
- 代理技能
- 狼蛛发射器
- 测试
- 添加或更改项目
- 重运行和幂等性
- 此处处理的 Fluxion 警告
- 引导程序后的手动步骤
- 可选模块
- 没有移植,为什么
- 更新中
- 故障排除
快速启动
从 本地 GNOME 会话 在计算机本身的终端中执行此操作,而不是通过 SSH。系统扁平化
polkit 仅对活动本地会话授权安装,并且 gsettings 需要会话总线。
先决条件:
- Ubuntu 26.04 LTS 桌面(“决心”),amd64,具有 sudo 权限的用户,网络访问权限。
git和curl(新的 Ubuntu 26.04 桌面两者都不附带)。- fluxion 0.4.1 或更高版本(请参阅 Fluxion 版本)。
bootstrap.sh将版本安装到~/.local/bin当它发现没有变化时,并且拒绝与较旧的变化一起申请。 - 首次运行大约需要 10 GB 的可用磁盘和几个小时。
# 1. prerequisites
sudo apt update && sudo apt install -y git curl
# 2. clone to the expected path (the profiles hard-code repoDir=$HOME/.ubuntu-bootstrap)
git clone [email protected]:w0rxbend/ubuntu-bootstrap.git ~/.ubuntu-bootstrap
cd ~/.ubuntu-bootstrap
# 3. (optional) run a fluxion build of your own instead of the release bootstrap.sh installs.
# fluxion-bin.local is git-ignored; bootstrap.sh, the tests and `just` all read it.
echo /path/to/fluxion > fluxion-bin.local # later: just use-fluxion /path/to/fluxion
# 4. see what would happen (read-only, no sudo)
./bootstrap.sh --validate # validate --strict + lint for every module
./bootstrap.sh --dry-run # exact commands per module
# 5. run it. sudo asks for your password once, and the script keeps the ticket warm
./bootstrap.sh
# ... it stops at the `session` log-out checkpoint (exit 0, summary says "checkpoint (log out/in)").
# 6. log out and back in (or reboot), then finish:
cd ~/.ubuntu-bootstrap && ./bootstrap.sh # converged: every module skips, no second log-out prompt
./bootstrap.sh --only post-checks # verification + reminders of the manual steps
dotfiles 模块克隆 w0rxbend/system-bootstrap 到
~/.system-bootstrap 通过 https(不需要 SSH 密钥)并从那里链接共享点文件;它取代的任何东西
首先将$HOME备份到~/.ubuntu-bootstrap-backup/。
运行是无人值守的:bootstrap.sh 传递了 --no-tui,因此 Fluxion 打印普通输出而不是打开其
每个模块的全屏选择器。添加 --tui 以获取选择器(按 enter 启动,按 q 关闭
运行后的屏幕)。在选择器上按 q 会跳过该模块,并且 Fluxion 仍会退出 0,因此
摘要将其报告为 ok,即使没有运行任何内容。
fluxion doctor -c profiles/00-base.yaml(来自 fluxion-bin.local 的 Fluxion)以只读方式检查主机。上一个
新主机 doctor 失败 30-toolchains.yaml 的 cargo-binstall command not found 和 pipx 命令不 found for optional/gnome-extensions.yaml。两者均由同一运行的早期 phase/module 安装
(rust 阶段和 base),因此在第一次应用之前预计会出现这两次失败。
要应用单个模块或模块内的单个阶段,而不运行所有内容:
./bootstrap.sh --only docker # one module (wrapper: PATH, sudo keep-alive, summary)
./bootstrap.sh --only apps,docker # several modules, in table order
# one phase, directly with fluxion (keep the module's state name; run `sudo -v` first; `fluxion` below means
# the build from fluxion-bin.local when there is one, e.g. alias fluxion="$(grep -v '^#' ~/.ubuntu-bootstrap/fluxion-bin.local | head -n1)"):
fluxion apply -c profiles/10-apps.yaml --profile apps --phase vscode --skip-already-installed
fluxion list -c profiles/10-apps.yaml # phase and step names of a module
fluxion graph -c profiles/10-apps.yaml # phase dependency graph (mermaid)
最后一个模块 (session) 更改您的组 (docker、libvirt、kvm) 和您的登录 shell。然后它停止
注销检查点:fluxion 退出 75,bootstrap.sh 在那里停止,打印要执行的操作并退出 0。阶段是
记录为已完成,因此下一次运行不会再次询问,并且 session 不会更改任何内容的运行(a
聚合主机(--re-probe)根本不会询问。重新登录还会加载 Vicinae GNOME Shell 扩展。退出
然后返回,或重新启动,然后运行:
cd ~/.ubuntu-bootstrap && ./bootstrap.sh --only post-checks
完整的演练,包括模块中途失败时该怎么做,是 首先在全新的 Ubuntu 上运行。
全新安装的完整运行需要一段时间。慢速部分是 TeX Live,大约 51 个 Flatpaks 和 22 个 snap,SDKMAN 候选者,
Miniforge 和 Nerd 字体,总计约 1.5 GB。当一个模块失败时,脚本继续执行下一个模块
one 并在最后打印摘要。修复失败的内容并重新运行该模块
./bootstrap.sh --only NAME.
bootstrap.sh 参考
./bootstrap.sh [--dry-run | --validate | --plan | --status | --failed | --list]
[--only a,b | --from NAME] [--yes] [--tui] [--show-output] [--re-probe]
[--test | --profiles-dir DIR] [--state-prefix P] [--report FILE]
| 旗帜 | 效果 |
|---|---|
| (无) | 按顺序为每个默认模块运行 fluxion apply --profile NAME --skip-already-installed --no-tui |
--dry-run |
运行 fluxion dry-run --no-tui:打印确切的命令并且不进行任何更改。没有须藤 |
--validate |
在每个选定的模块上运行 fluxion validate --strict 和 fluxion lint |
--plan |
运行 fluxion plan --format tree |
--status / --failed |
运行 fluxion status --summary / --failed:只读实时探针 |
--list |
列出模块及其文件 |
--only a,b |
仅选择这些模块(默认或可选)。他们总是按表顺序运行 |
--from NAME |
在 NAME 处恢复默认序列 |
--tui |
为每个模块打开 Fluxion 的交互式 selector/TUI,而不是普通输出(仅适用) |
--no-tui |
默认;因兼容性而接受 |
--yes, --show-output, --re-probe |
穿越到流变 |
--test |
运行生成的测试配置文件(tests/generated/,首先重新生成),状态名称为 test-NAME。相同的编排,相同的模块;参见 测试 |
--profiles-dir DIR |
从 DIR 而不是 profiles/ 读取每个模块的配置文件(相同的相对布局) |
--state-prefix P |
为 Fluxion 状态名称添加前缀(--test 使用 test-) |
--report FILE |
为每个模块附加一个制表符分隔行:名称、rc、结果、秒数和 Fluxion 的 Summary: 计数(正常、失败、跳过、将运行) |
哪个fluxion运行在一个地方决定,scripts/lib/fluxion-bin.sh,由bootstrap.sh共享,
tests/run-tests.sh、scripts/validate-all.sh 和 Justfile:设置时为 $FLUXION_BIN,否则为路径中的路径
git-ignored fluxion-bin.local (just use-fluxion PATH writes it), else fluxion on PATH, else bootstrap.sh
安装 Fluxion 版本。因此,测试运行的二进制文件是真正引导程序运行的二进制文件。配置文件自己的
脚本通过导出的 FLUXION_BIN 获得相同的二进制文件。
在任何模块运行之前,脚本都会执行以下检查和设置步骤:
- 它拒绝以 root 身份运行。
- 如果存储库不在
~/.ubuntu-bootstrap、如果您通过 SSH 连接或者主机不在 SSH,它会发出警告 Ubuntu 26.04“坚决”。 - 它按照上面的方式解析流数并打印哪一个流数以及它来自哪里。在应用模式下它拒绝流变
早于 0.4.1(
scripts/lib/fluxion-bin.sh中的FLUXION_MIN_VERSION,与fluxion --version相比) 并说明如何安装该版本。FLUXION_ALLOW_UNPATCHED=1将其变成警告;只读模式 只是警告。 - 它导出 PATH,其中包括模块创建的每个工具位置:
~/.cargo/bin、~/.local/bin、~/.go/bin、~/.apps/{dotbot,neovim,yq,helm,kustomize}/bin、~/.local/share/pnpm/bin和 juliaup。 - 它运行一次
sudo -v(当sudo -n true已经工作时跳过,e.g。在NOPASSWD下,其中sudo -v可以 仍然要求输入密码),然后每 50 秒刷新一次票证,直到脚本退出。
每个模块在应用之前都会经过验证。退出代码为0表示一切成功或注销 已达到检查点,当任何模块失败时为 1。
该脚本永远不会看到您的密码。 sudo 直接提示,fluxion 只调用 sudo -n。
just 快捷键
just 由 toolchains 模块安装,因此仅在首次运行后可用。
| 食谱 | 跑步 |
|---|---|
just bootstrap / just dry-run / just validate / just list |
完整运行、空运行、scripts/validate-all.sh 和模块列表 |
just apply NAME |
./bootstrap.sh --only NAME(NAME可以是a,b) |
just from NAME |
在 NAME 处恢复默认序列 |
just dry NAME / just plan NAME |
试运行或计划一个模块 |
just status [a,b] / just failed [a,b] |
实时探测摘要,或仅缺失和失败的项目 |
just state NAME / just state-reset NAME |
显示或删除为模块记录的 Fluxion 状态 |
just use-fluxion PATH |
写入 fluxion-bin.local (git-ignored),以便每个脚本运行该 Fluxion 构建,并检查它是否有修复 |
just dotfiles / just dotfiles-dry / just dotfiles-check |
scripts/dotfiles-link.sh:备份+重新链接所有内容、预览或验证每个链接 |
just dotfiles-pull |
scripts/system-bootstrap-sync.sh:克隆~/.system-bootstrap或快进 |
just skills |
scripts/link-skills.sh:将每个已安装的代理链接到共享技能文件夹 |
just test [ARGS] / just test-validate / just test-assert / just test-gen |
tests/run-tests.sh(所有阶段/只读验证+空运行/仅断言),重新生成tests/generated/ |
just vicinae |
./bootstrap.sh --only vicinae |
just update |
~/system-update.sh(apt、snap、flatpak、rustup、SDKMAN、nvm、...) |
just refresh-binaries / just refresh-fonts |
重新运行 binstaller 阶段/四个 Nerd Font 阶段,无需 --skip-already-installed(请参阅 更新) |
just obs / gnome-extensions / wallpapers / post-checks |
可选模块 |
首先在新的 Ubuntu 上运行,一步一步
下面的一切都发生在机器本身上登录的 GNOME 会话内的终端中(不是通过 SSH):
系统 flatpak 安装仅由 polkit 授权用于活动本地会话,并且 gsettings 需要该会话
巴士。
-
基础工具和存储库。
sudo apt update && sudo apt install -y git curl git clone [email protected]:w0rxbend/ubuntu-bootstrap.git ~/.ubuntu-bootstrap && cd ~/.ubuntu-bootstrap -
fluxion. 无需执行任何操作:
./bootstrap.sh将FLUXION_VERSION(v0.4.1) 命名的版本安装到~/.local/bin当它没有找到时。要手动安装它或替换旧的:curl --proto '=https' --tlsv1.2 -sSfL https://worxbend.github.io/fluxion.cr/install.sh | sh -s -- --version v0.4.1要运行您自己的构建(fluxion.cr 结账:来自
crystal经典快照的 Crystal >= 1.21, 加上build-essential pkg-config libyaml-dev libssl-dev libpcre2-dev zlib1g-dev):cd ~/Projects/fluxion.cr && shards install && crystal build --release --no-debug src/main.cr -o bin/fluxion echo ~/Projects/fluxion.cr/bin/fluxion > ~/.ubuntu-bootstrap/fluxion-bin.local && cd ~/.ubuntu-bootstrap./bootstrap.sh --validate然后打印using fluxion 0.4.1 (<path>, from fluxion-bin.local),并警告如果 构建版本早于回购需求。 -
预览(可选,只读):
./bootstrap.sh --validate和./bootstrap.sh --dry-run。 -
运行默认序列:
./bootstrap.sh。 sudo 会询问您一次密码(在 NOPASSWD 下跳过)。的 十一个模块按顺序运行;失败的模块不会阻止其他模块,最后的摘要列出了每个模块 模块的结果。如果失败,请阅读./bootstrap.sh --failed --only NAME,修复原因,然后重新运行 (./bootstrap.sh --only NAME)或恢复序列(./bootstrap.sh --from NAME,其中失败 给您的消息名称)。已完成的项目会从记录状态中跳过,因此重新运行的成本很低。 Ctrl+C 是 也很安全:fluxion 记录其停止的位置,而./bootstrap.sh(或--from NAME)继续进行。 -
注销提示。 最后一个模块
session将 zsh 设置为您的登录 shell 并将您添加到docker,libvirt和kvm,然后在检查点停止:fluxion 打印 需要重新启动,摘要显示session ... 75 checkpoint (log out/in)和bootstrap.sh退出 0 并运行下一个命令。 注销并 返回,或重新启动。 这将使组和登录 shell 生效并加载 Vicinae GNOME 扩展。 -
重新登录后恢复:
cd ~/.ubuntu-bootstrap ./bootstrap.sh # optional: re-checks the whole sequence; everything is skipped, no new prompt ./bootstrap.sh --only post-checks # docker without sudo, zsh, fonts, nvim, CLIs, Vicinae server + extensionpost-checks还保留手动步骤的提醒(gh 登录、SSH 密钥、重复的 TG 平台 flatpak)。它 退出 1 并命名每一个,直到完成为止;这是预期的,请参阅 引导程序 之后的手动步骤。 -
可选模块(当您需要时):
./bootstrap.sh --only obs,wallpapers,gnome-extensions。日志out/in 在gnome-extensions之后再次。 -
验证(可选):
tests/run-tests.sh来自 GNOME 会话运行整个套件(应用 + 幂等性 + 对测试配置文件的断言,加上仅生产状态);请参阅 测试。
流变版本
此仓库需要 fluxion 0.4.1 或更高版本(scripts/lib/fluxion-bin.sh 中的 FLUXION_MIN_VERSION;bootstrap.sh
并且测试拒绝应用于较旧的测试,FLUXION_ALLOW_UNPATCHED=1 覆盖)。 bootstrap.sh 安装
FLUXION_VERSION (v0.4.1) 当发现没有通量时;运行您自己的构建,just use-fluxion PATH(请参阅
首先运行)。
此存储库所需的修复是在 fluxion.cr 分支 fix/zorin-bootstrap 上编写的(以此存储库的 Zorin 命名)
OS 起源)并在 fluxion 0.4.0 中发布
(worxbend/fluxion.cr#2):
| 提交 | 修复 | 为什么这个仓库需要它 |
|---|---|---|
d26a299, d6f0caf |
apt probe reads dpkg-query output correctly; a package held with apt-mark hold counts as installed |
0.3.1 探测每个 apt 软件包都不存在,因此 status 是错误的,--re-probe 重新安装了约 200 个软件包 |
49aae0a, 95fe904 |
每个包列表一个 apt-get install,仅在失败时一一对应;不在 Ctrl+C 之后 |
200 个包阶段运行一个事务而不是 200 个事务 |
4c30b6d, 149f1d8 |
system-setting 项目和断言由 status 回答 |
base 时钟设置和每个 host-check 显示为未知 |
af2c932 |
每次运行时都会检查断言,从不信任状态 | 诸如 gnome-session-check 之类的守卫和重新运行的后检查 |
f992d37, 5d19083, c34113b, eded4b5 |
apt sources must match the declared line and keyring; a keyring must hold the declared fingerprint; gpg keys are read with a throwaway gpg home (fresh accounts have no ~/.gnupg) and an unusable TMPDIR fails one item instead of the run |
apps(claude-desktop、VS 代码、1Password、水晶钥匙) |
9d7b731, 16712e6, 82f3e77 |
cargo crates and SDKMAN candidates have live probes | toolchains --re-probe 下的幂等性 |
8065313, 953e35e |
binstaller 固定到 v0.5.0(读取 GNU @LongLink tar 条目) |
否则,binaries 在 zig 0.15.2 上失败 |
9a77b8f |
步骤的 probeCommand 每一步结算一次,而不是在每个项目之前结算 |
多脚本步骤 (vicinae) 跳过了后面的脚本 |
4254ceb, d699c4a |
prompt-logout 阶段被记录为已完成并退出 75,并且仅询问何时更改了某些内容 |
session:一次注销提示,不是每次运行一次; --re-probe 运行完成 |
7430ef4, 7e01f16 |
flatpak 探针看到扩展(运行时参考) | obs 插件安装后显示不存在 |
bdf915b |
fluxion state forget 将配置文件作为位置参数 |
记录的 state forget 命令 |
241e8f1, 0da747d |
每个文件的代码拆分为 500 行以下;记录的与 Java 规范的差异 | 上游卫生,无行为改变 |
fluxion 0.4.1(worxbend/fluxion.cr#3 及之后)添加了以下内容 第一次在Ubuntu 26.04上运行发现:
| 提交 | 修复 | 为什么这个仓库需要它 |
|---|---|---|
0fb69d5 |
特权命令可能是根拥有的符号链接到另一个根拥有的树 | Ubuntu 26.04 将 coreutils 作为 Rust uutils 提供:/usr/bin/install 和 chown 链接到 /usr/lib/cargo/bin/coreutils,并且 0.4.0 拒绝它们(“无法从受信任的 root 拥有的系统目录中获取”),因此每个 apt-repository 步骤和特权文件写入都会失败 |
e88f6c0 |
声明的 probeCommand 类型 0.4.0 的答案给出了类型化探针 |
配置文件自己的探针仍然负责 |
8aa709f |
报告每个批次的包裹;跨运行保留欠注销 | 正确的总结; session 中断运行后仍然询问 |
55ae3f7 |
等待另一个进程持有的包管理器锁(5 秒到 30 秒的暂停,最多 15 分钟) | 新的桌面在安装后立即运行无人值守升级,这通常会在第一个 apt 阶段失败 |
要迁移到较新的版本:在 bootstrap.sh 中设置 FLUXION_VERSION,如果 repo 出现,则提高 FLUXION_MIN_VERSION
要依赖它,请安装它,并删除 fluxion-bin.local(如果它指向较旧的版本)。
它是如何运作的
Fluxion没有包含机制,因此每个模块都是profiles/中的完整、独立的WorkstationProfile。
bootstrap.sh 依次运行它们。每个模块都有自己的自己的状态名称(--profile base,
--profile docker,...),因此其状态位于 ~/.local/share/fluxion/<name>.state.json 中。
以这种方式拆分设置会产生以下后果:
- 每个模块都在一个新的 Fluxion 进程中运行。 Fluxion 在加载时读取 PATH 并仅评估
when:一次。工具 因此,由早期模块(cargo-binstall、dotbot、broot、gext)安装的模块对于后续模块是可见的。 - 模块可以自行重新运行、重置或调试。
- 一个模块的故障不会阻塞其他模块。在模块内部,最有可能失败的列表(flatpaks、snap、 curl installers) sit in leaf phases that no other phase depends on.
- 唯一的
prompt-logout阶段位于最后一个模块session中,因此其他模块的空运行永远不会被切断 短。生成的测试配置文件完全放弃了它。 dotfiles故意迟到。多个安装程序(pnpm、codex、kimi)将行附加到~/.zshrc。在它们后面运行 dotbot 意味着这些行落在一次性 oh-my-zsh 模板中(该模板受支持) 最多~/.ubuntu-bootstrap-backup/.zshrc),然后 dotbot 将其替换为以下链接~/.system-bootstrap/.files/.zshrc。如果 dotbot 首先运行,安装程序将编辑共享文件。
每个配置文件都以 host-check 开头,断言主机是 Ubuntu 26.04“坚决”,带有 apt-get,并且
声明 target.os ubuntu/resolute/26.04。配置文件不使用 when: {distribution: ubuntu}:每个配置文件都是
已经仅限 Ubuntu。
布局
~/.ubuntu-bootstrap/
├── README.md
├── Justfile # shortcuts (just is installed by `toolchains`)
├── bootstrap.sh # ordered runner: preflight, sudo keep-alive, summary (--test for the tests)
├── .gitignore .editorconfig .shellcheckrc
├── fluxion-bin.local # git-ignored, optional: a fluxion build to run instead of the one on PATH
├── scripts/
│ ├── lib/fluxion-bin.sh # the one fluxion resolver + minimum-version check (bootstrap, tests, just)
│ ├── validate-all.sh # validate --strict + lint (prod + test profiles), bash -n + shellcheck
│ ├── system-bootstrap-sync.sh # clone ~/.system-bootstrap (https) or fast-forward it; --check
│ ├── dotfiles-link.sh # back up what is in the way, run dotbot for both configs; --check/--dry-run
│ └── link-skills.sh # POSIX sh: <agent>/skills -> ~/.agents/skills for installed agents
├── profiles/
│ ├── 00-base.yaml # base
│ ├── 10-apps.yaml # apps
│ ├── 20-docker.yaml # docker
│ ├── 30-toolchains.yaml # toolchains
│ ├── 40-binaries.yaml # binaries
│ ├── 50-shell.yaml # shell
│ ├── 60-desktop-apps.yaml # desktop-apps
│ ├── 70-gnome.yaml # gnome
│ ├── 75-vicinae.yaml # vicinae
│ ├── 80-dotfiles.yaml # dotfiles
│ ├── 90-session.yaml # session (log-out checkpoint)
│ └── optional/
│ ├── obs.yaml
│ ├── gnome-extensions.yaml
│ ├── wallpapers.yaml
│ └── post-checks.yaml
├── config/
│ ├── binstaller.yaml # binstaller profile, an Ubuntu fork (also linked to ~/.config/binstaller/config.yaml)
│ └── nerd-fonts/
│ ├── 01-core.yaml 02-more.yaml 03-rest.yaml 04-noto.yaml # batches fluxion uses; together they
│ # equal the clone's .config/nerd-fonts-installer/config.yaml (all 42 families)
├── dotfiles/ # ONLY Ubuntu-specific files; shared dotfiles come from ~/.system-bootstrap
│ ├── system-bootstrap.conf.yaml # dotbot config, base dir ~/.system-bootstrap/.files (the live clone)
│ ├── install.conf.yaml # dotbot config, base dir dotfiles/ (the Ubuntu-only files below)
│ ├── custom.zsh # -> ~/.custom.zsh, sourced by the shared .zshrc (Ubuntu PATH + ubuntu plugin)
│ ├── ubuntu-system-update.sh # -> ~/system-update.sh
│ ├── .config/xdg-terminals.list .config/environment.d/90-session.conf # kitty as terminal, session env
│ └── agents/skills/ # the shared agent skills (README.md explains the layout)
└── tests/
├── gen-test-profiles.sh # profiles/ -> tests/generated/ (halting steps removed)
├── run-tests.sh # validate, apply, idempotency re-apply, assertions; --container
├── generated/ # git-ignored, regenerated before every use
├── assertions/ # lib.sh + one <module>.sh per module (the real post-conditions)
├── container/Dockerfile # "fresh Ubuntu Desktop" image for --container (ubuntu:26.04 + baseline)
├── container/ubuntu-baseline.txt # what that image adds: Ubuntu-Desktop-shipped CLI packages (+ git, curl), delta documented
├── lib/ # generator, profile queries, inline-snippet extractor, dotfile-copy detector
│ # (find_copies.py), uinput key presser (python3 + PyYAML)
└── logs/ # git-ignored run logs
~/.system-bootstrap/ # live clone of github.com/w0rxbend/system-bootstrap (source of truth)
└── .files/ # .zshrc, nvim, kitty.conf, .tmux.conf, starship, alacritty, .config/...
配置文件内的相对路径从配置文件自己的目录解析。这就是为什么 profiles/*.yaml 引用
../config/... 和 profiles/optional/*.yaml 指 ../../...。
模块
默认序列(./bootstrap.sh):
| # | 模块 | 文件 | 它的作用 |
|---|---|---|---|
| 1 | base |
profiles/00-base.yaml |
修复损坏的 Crystal apt 源、apt full-upgrade、debconf 预置、大约 190 个 Ubuntu 存档包(CLI、构建、调试、GUI-dev、媒体、字体、TeX、桌面、虚拟化)、GPU 选择的工具lspci、libvirtd、全局 git 配置、NTP 时钟、bat 符号链接 |
| 2 | apps |
profiles/10-apps.yaml |
第三方应用程序:GitHub CLI、Claude Desktop、1Password(apt repos)、ChatGPT 和 fastfetch(.deb)、VS Code 和 Crystal(经典快照) |
| 3 | docker |
profiles/20-docker.yaml |
Docker CE、buildx 和来自 Docker apt 存储库的 compose 插件、docker/containerd 服务、distrobox |
| 4 | toolchains |
profiles/30-toolchains.yaml |
rustup, cargo-binstall and 14 crates, Go 1.27.1, SDKMAN and 8 candidates, nvm and Node LTS, pnpm, pyenv, poetry, uv, Miniforge, juliaup, kustomize, helm 4, dotenvx |
| 5 | binaries |
profiles/40-binaries.yaml |
binstaller配置文件(~/.apps中的13个工具),/usr/local/bin中的nvim/vim链接,4批Nerd字体 |
| 6 | shell |
profiles/50-shell.yaml |
oh-my-zsh(固定)和 3 个插件,TPM、starship、kitty(上游构建、桌面集成、x-terminal-emulator 替代)、ghostty snap |
| 7 | desktop-apps |
profiles/60-desktop-apps.yaml |
flatpak 和 Flathub 遥控器、类别组中的 51 个 flatpaks、20 个快照、Claude Code、Codex 和 Kimi CLIs、Zed、Paseo |
| 8 | gnome |
profiles/70-gnome.yaml |
9 个固定工作区、Super+N / Super+Shift+N 绑定、屏幕截图键、Ubuntu Dock 热键关闭、固定收藏夹 |
| 9 | vicinae |
profiles/75-vicinae.yaml |
Vicinae 启动器(通过官方脚本将 AppImage 固定到 /usr/local 中)、其 systemd 用户服务、vicinae@dagimg-dot GNOME 扩展、Super+D 切换 |
| 10 | dotfiles |
profiles/80-dotfiles.yaml |
Clones/fast-forwards ~/.system-bootstrap,备份阻碍的内容,链接两个 dotbot 配置(来自克隆的共享点文件、来自此存储库的仅 Ubuntu 文件和代理技能)、tmux 插件、broot 启动器 |
| 11 | session |
profiles/90-session.yaml |
zsh 作为登录 shell,docker/libvirt/kvm 组,注销检查点 |
可选模块(./bootstrap.sh --only NAME):
| 模块 | 它的作用 |
|---|---|
obs |
OBS Studio 和 10 个 flatpak 插件(DroidCam、背景去除、VAAPI、PipeWire 视频、...) |
gnome-extensions |
gext (pipx) 加上用户主题、电池指示器图标、通知图标、礼帽、空格键、AlphabeticalAppGrid,随 gext -F 一起安装(无 GNOME Shell 对话框) |
wallpapers |
将旧存储库中的壁纸稀疏克隆到 ~/.local/share/backgrounds/system-bootstrap(约 109 个 MB) |
post-checks |
重新登录后运行。检查 docker 组、docker run hello-world、zsh 登录 shell、字体、nvim、核心 CLIs、Vicinae 服务器应答且其扩展处于活动状态,然后提醒您手动步骤。在重新登录之前运行,仅对 docker-group、docker run 和扩展检查失败(--show-output 表示是否缺少日志 out/in) |
库存齐全
配置文件具有每个项目的确切规格。本节是一个快速总结。
base :Ubuntu 存档
| 集团 | 套餐 |
|---|---|
| 核心 | ca-certificates curl wget gnupg git zsh unzip zip xz-utils fontconfig fusion3 libfuse2t64 software-properties-common debconf-utils apt-transport-https pciutils python3-yaml(由点文件和测试脚本使用) |
| CLI | alacritty bat btop fzf htop tmux wl-clipboard jq net-tools hyperfine asciinema gdu xsensors lm-sensors 应力 zoxy tig wev foot mtr nmap httpie ripgrep pipx stacer tree mediainfo libimage-exiftool-perl imagemagick poppler-utils ffmpegthumbnailer 7zip python3-venv python3-pip python3-dev |
| 建造 | build-essential gcc g++ pkg-config clang clangd clang-format clang-tidy clang-tools llvm llvm-dev libclang-dev libclang-rt-dev lld lldb make cmake meson ninja-build ccache flex bison gperf,加上 pyenv、Python、Rust 和 Crystal 构建所需的 -dev 库(readline、ffi、ssl、zlib、bz2、 sqlite3、lzma、tk、ncurses、xml2、xmlsec1、secret、yaml、gmp)和 dfu-util |
| 调试 | gdb valgrind strace ltrace linux-tools-common linux-tools-generic-hwe-26.04 tshark protobuf-编译器 |
| GUI 开发者 | GTK 3/4 和 GObject-introspection 开发包、WebKitGTK 6、X11/Xcursor/Xrandr/Xi/Xinerama 开发、Mesa/GL/EGL/GBM 开发、mesa-utils(无 mesa-vdpau-drivers:Mesa 25 已删除) VDPAU) |
| 媒体 | vlc mpv imv ffmpeg、libav* 开发包、GStreamer 插件集 (base/good/bad/ugly/libav/vaapi/pipewire)、libopenh264-8、VA-API(mesa-libgallium,在 26.04 上携带 Mesa 的 VA 驱动程序)、 libvdpau-va-gl1 和 vainfo、PipeWire 和wireplumber、easyeffects、power-profiles-daemon、upower、ubuntu-restricted-extras(EULA 预置)、v4l2loopback-dkms 和 HWE 标头 |
| 字体 / TeX | 字体-firacode 字体-字体-真棒字体-noto-核心字体-noto-颜色-表情符号字体-roboto,texlive-base/latex-base/latex-recommended/fonts-recommended/xetex |
| 桌面 | gnome-tweaks、shell 扩展首选项和扩展、gnome-browser-connector、xdg-desktop-portal-gtk、gnome-keyring、libpam-gnome-keyring、seahorse、gcr、gcr4、zathura (+pdf-poppler)、mupdf |
GPU(由 lspci,如旧脚本中所示) |
当存在 AMD GPU 时为 radeontop,当存在 Intel GPU 时为 intel-media-va-driver (iHD VA-API);除此之外什么也没有 |
| 虚拟 | qemu-system-x86 qemu-utils ovmf libvirt-daemon-system libvirt-clients virtinst virt-managerbridge-utils dnsmasq-base vde2 netcat-openbsd cpu-checker,加上 libvirtd.socket 启用并侦听(libvirtd.service 启用;它是套接字激活的,并在 120 后退出空闲) |
| 配置 | git user.email, user.name = w0rxbend, pull.rebase=true, init.defaultBranch=main, core.autocrlf=input; NTP on and RTC in UTC; ~/.local/bin/bat pointing to batcat |
在任何东西运行 apt-get update 之前,apt-sources-repair 阶段将主机获得的损坏的水晶源移到一边
来自curl -fsSL https://crystal-lang.org/install.sh | sudo zsh (see Troubleshooting). It does
当文件不存在或正确时,什么也没有。
Debconf preseeds 首先运行:它们接受 mscorefonts EULA 并将wireshark 设置为 install-setuid=false。流变确实
未设置 DEBIAN_FRONTEND,因此如果没有预置,这些包可能会挂起等待答案。
apps :第三方应用程序(这些是在此主机上手动安装的)
| 应用程序 | 来源 |
|---|---|
gh |
cli.github.com/packages 存储库,钥匙圈 /etc/apt/keyrings/githubcli-archive-keyring.gpg(sha256 固定) |
claude-desktop |
downloads.claude.ai/claude-desktop/apt/stable 存储库,钥匙圈 /usr/share/keyrings/claude-desktop-archive-keyring.gpg。它为其 VM 引入 qemu、ovmf 和 virtiofsd |
code |
code经典snap(VS代码),由snapd刷新 |
1password |
1 密码密钥(已固定指纹)和一个与软件包中写入的文件相同的 1password.sources 文件 |
ch@tgpt |
persistent.oaistatic.com 的最新 .deb。它的 postinst 添加了存储库和密钥环,因为没有公钥 URL |
fastfetch |
fastfetch GitHub 版本中的最新 .deb(比 resolute archive 版本更新) |
crystal |
crystal 经典快照(撰写本文时为 Crystal 1.21.1,带有 shards),由 snapd 刷新。切勿在其旁边安装 Ubuntu 的 crystal/shards apt 软件包:/usr/bin 位于 PATH 上的 /snap/bin 之前,因此它们会隐藏它 |
勇敢没有被感动。在此主机上,它是手动安装的 brave 管理单元。
claude-desktop 包的 postinst 会在每个
安装和升级。该文件是无害的。这里写的claude-desktop.list没有###管理的 克劳德桌面 package. marker, so the postinst leaves it alone and it keeps pointing at the dearmored .gpg。
docker
请参阅 Docker 而不是 podman。
toolchains :用户级,无sudo
| 工具 | 如何 | 哪里 |
|---|---|---|
| 铁锈 | rustup (sha256-pinned script, --no-modify-path) |
~/.cargo, ~/.rustup |
| cargo-binstall | 固定的上游安装脚本 | ~/.cargo/bin |
| 板条箱(cargo-binstall) | eza lsd fd-find bingrep hx just sd procs du-dust gping 树保姆-cli macchina 底部 broot | ~/.cargo/bin |
| 去1.27.1 | 官方 tarball,经过 sha256 检查 | ~/.go, GOPATH=~/.go-workspace |
| SDKMAN | get.sdkman.io(sha256 固定),使用 bash 运行,自动应答 |
~/.sdkman |
| SDKMAN 候选人 | java gradle maven sbt scala micronaut vertx VisualVM(最新默认值) | ~/.sdkman/candidates |
| nvm 和节点 LTS | nvm v0.40.7(sha256 固定),nvm install --lts,默认别名 lts/* |
~/.nvm |
| pnpm | get.pnpm.io (PNPM_HOME=~/.local/share/pnpm) |
~/.local/share/pnpm/bin(pnpm 11+ 布局) |
| pyenv | pyenv.run(sha256 引脚) |
~/.pyenv |
| 诗歌/紫外线 | 官方安装程序 | ~/.local/bin |
| 小型锻造厂 | 最新Miniforge3-Linux-x86_64.sh,批处理模式 |
~/.miniforge3 |
| 朱利亚普 | install.julialang.org(sha256 引脚) |
~/.juliaup |
| 定制/舵 4 | 上游安装脚本,无需 sudo(helm 的脚本需要其位于 PATH 上的目录,这是该步骤设置的) | ~/.apps/{kustomize,helm}/bin |
| 多特恩克斯 | dotenvx.sh |
~/.local/bin |
hx 是 satkevij 的十六进制查看器,而不是 Helix。
binaries
-
binstaller(
config/binstaller.yaml,模式developer,appsDir: ~/.apps):yazi v26.5.6,zig 0.15.2,minikube, xplr,种类 v0.31.0,zellij v0.44.1,kubectl(稳定),neovide(AppImage),neovim(最新),lazygit 0.61.0, jujutsu v0.40.0、dotbot v0.4.2 和 yq (mikefarah,新添加)。每个工具都有自己的~/.apps/<tool>/bin. 需要 binstaller >= v0.3.0。 Fluxion 0.3.1 固定 binstaller v0.2.0,并且该版本无法读取 GNU@LongLinktar 条目位于zig-x86_64-linux-0.15.2.tar.xz中,因此 binstaller 步骤在 zig 上失败。通量0.4.0 以及后来的引脚 v0.5.0(参见 Fluxion 版本)。 将installerVersion排除在配置文件之外:fluxion 仅接受其自己的固定版本。 -
nvim系统链接:
/usr/local/bin/{nvim,neovim,vim}指向~/.apps/neovim/bin/nvim,所以sudo vim也 打开你的 Neovim。/usr/bin属于dpkg,未被触及。 binstaller 自己的 sudo 符号链接已关闭。 -
Nerd Fonts (nerd-fonts-installer,
~/.local/share/fonts/NerdFonts),分 4 批安装,因为 Fluxion 给该类型一个固定的 15 分钟超时:01-core:JetBrainsMono,VictorMono,FiraCode,FiraMono,SymbolsOnly,CascadiaCode,Meslo,黑客, SourceCodePro, UbuntuMono, Ubuntu, ZedMono, GeistMono, CommitMono02-more:MPlus、总站、FantasqueSansMono、HeavyData、3270、LiberationMono、RobotoMono、Mononoki、 DroidSansMono, Monoid, SpaceMono, ComicShannsMono, DaddyTimeMono, CodeNewRoman03-rest:Hasklig、DejaVuSansMono、Inconsolata、隐士、龙舌兰、Monaspace、ShareTechMono、递归、D2Coding、 EnvyCodeR, IosevkaTerm, Lekton, Lilex04-noto:诺托,很大
终端依赖于 VictorMono (alacrtty、ghostty、wezterm) 和 FiraCode (kitty)。
shell
oh-my-zsh(固定修订版和 sha256)、zsh-syntax-highlighting、zsh-autosuggestions、zsh-history-substring-search
(固定提交)、TPM(固定)、starship (~/.local/bin) 和来自上游安装程序的 kitty
(~/.local/kitty.app)。 kitty 的桌面集成与我在 bash 中手动执行的操作相匹配:kitty/kitten 链接
具有绝对 Icon/Exec 路径的 ~/.local/bin 和 .desktop 文件。 kitty 也被注册并选为
x-terminal-emulator 替代方案(优先级 60),Debian 工具会使用该替代方案。 Ubuntu 26.04 上的 GNOME/GLib 询问
xdg-terminal-exec(默认安装,以 Ptyxis 为种子),dotfiles 模块通过它指向 kitty
~/.config/{,ubuntu-,gnome-}xdg-terminals.list。 幽灵快照使用经典的限制。 zsh本身来自base,登录shell的更改发生在session中。
desktop-apps
- 来自 apt 的 flatpak 和 Flathub 远程(描述符是 sha256 固定的)。 Ubuntu 两者都不提供;它 默认为快照。
- Flatpaks(共 51 个,每组一个叶相,
continueOnError):- 浏览器:LibreWolf、Chrome、Zen
- 沟通:不和谐
- 媒体: Audacity、AudioTube、ncspot、Decibels、Amberol、G4Music
- 图形:Kdenlive、Inkscape、Krita、Blender、FreeCAD、Godot、LibreCAD、BambuStudio、展览
- 写作:TextPieces、撇号、Bookup、Censor、Logseq
- dev: WezTerm, VSCodium (Ptyxis 已经是 Ubuntu 的默认终端了,来自 apt)
- 系统:扩展管理器、Flatseal、Flatsweep、仓库、资源、精炼、任务中心、Gradia、列表、 Authenticator, Polari, D-Spy, Rewaita, Emblem, Mozilla , NetPeek, GNOME Boxes, Gear Lever
- 生产力:会话、毯子、包、LocalSend、NewsFlash、剂量、健康
- 快照(在此主机上手动安装;
continueOnError):brave、telegram-desktop、vesktop-tsugu(Vesktop),zulip,slack,spotify,mailspring,beekeeper-studio,onlyoffice-desktopeditors,zenkit-todo和glab一步完成,再加上每个经典快照一步:sublime-text、theia-ide、workshop、waveterm、jupyterlab-desktop、antigravity、antigravity-ide-snap、flutter和skuberplus-client。 OBS 就是这个 例外:它在可选的obs模块中保留为 Flatpak。 - AI CLIs:克劳德代码 (
claude.ai/install.sh)、OpenAI 代码 ([email protected]/codex/install.sh) 和 Kimi 代码 (code.kimi.com,使用 bash 运行,因为在此主机上使用 zsh 运行失败)。 - Home-dir 应用程序:Zed (
zed.dev/install.sh) 和 Paseo,在 Gear Lever 在此主机上提供的布局中:~/AppImages/paseo.appimage,图标~/AppImages/.icons/paseo(摘自 AppImage),启动器~/.local/share/applications/paseo.desktop(paseo://URL 处理程序、StartupWMClass=Paseo)和~/.local/bin/paseo链接。保留现有启动器,当 AppImage 已存在时,不会下载任何内容 那里。
粗体中的项目是在此主机的历史记录或程序包日志中找到的。
gnome
关闭动态工作区并设置 9 个工作区。 Super+1..9 切换工作空间,Super+Shift+1..9 移动工作空间
那里有窗口,就像在 Fedora 上一样。默认switch-to-application-N绑定被清除,截图UI开启
Super+Print 和 Print。 Ubuntu Dock 的 hot-keys 设置([email protected],dash-to-dock
使用 org.gnome.shell.extensions.dash-to-dock 模式构建(默认情况下为 hot-keys=true)已关闭,因为
它抓取 Super+1..9 和 Shift+Super+1..9 来启动固定应用程序;否则,工作区绑定永远不会触发。探头(和
tests/assertions/gnome.sh)还会扫描每个 gsettings 键以查找这些快捷方式的任何其他持有者。该模块必须
在登录的 GNOME 会话中运行并断言 DBUS_SESSION_BUS_ADDRESS 已设置。
它还将 dash/taskbar 收藏夹设置为我手动固定的内容:Brave、Files、Software、Ghostty、Terminal、
TG 平台(快照)、Vesktop、ChatGPT、Claude 和 Paseo (org.gnome.shell favorite-apps)。 gnome 在 apps 之后运行,
shell 和 desktop-apps,所以 .desktop IDs 那时就存在。该列表仅在 Vesktop 捕捉 (vesktop-tsugu_vesktop-tsugu.desktop) 时写入
尚未固定,因此稍后手动更改的引脚将被保留。断言如下:它需要 Vesktop 并且仅
报告(跳过)其他声明的手动移除的引脚。
tests/assertions/gnome.sh 还检查正在运行的 mutter 有 9 个工作区(_NET_NUMBER_OF_DESKTOPS 在
Xwayland 根窗口)。对于 ASSERT_LIVE_INPUT=1,它更进一步:它按下 Super+3,然后按下 Super+1
临时 /dev/uinput 键盘(tests/lib/uinput_keys.py,需要 sudo -n)并检查会话是否确实
切换工作区。该检查默认处于关闭状态,因为它将按键发送到桌面。
vicinae
请参阅 Vicinae 启动器。
dotfiles 和 session
请参阅 Dotfiles 与 dotbot 和 代理技能。 session 套 /usr/bin/zsh
作为您的登录 shell 并将您添加到 docker、libvirt 和 kvm。然后它会要求您注销。
Docker 代替 podman
旧的 Fedora 设置使用 podman、podman-docker、toolbox 和 buildah。在 Ubuntu 上,这些被替换为 Docker CE
来自 Docker 的官方 apt 存储库。 Ubuntu的docker.io没有使用。
| 什么 | 价值 |
|---|---|
| 回购协议 | deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu resolute stable 中 /etc/apt/sources.list.d/docker.list |
| 钥匙 | https://download.docker.com/linux/ubuntu/gpg,sha256 引脚,指纹 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 |
| 套餐 | docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin |
| 服务 | docker 和 containerd 启用并启动 |
| 冲突 | 首先删除 docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc(如果存在) |
| 集团 | docker,在session中添加。 注销并重新登录后生效 |
| 工具箱更换 | distrobox 1.8.2.5从上游发布tarball(sha256固定),与--prefix ~/.local一起安装到~/.local/bin中; uidmap 来自 apt。它自动使用docker |
注意事项:
- distrobox 不取自 apt:Ubuntu 的
distrobox软件包依赖于podman | docker.io, anddocker.io与docker-ce冲突,因此 apt 会将 podman 拉回来。通过distroboxVersion/ 进行碰撞distroboxSha256中的profiles/20-docker.yaml。 - 该套件的字面意思是
resolute(Docker 发布 26.04 软件包;密钥与旧套件相同)。 - Compose 是 v2 插件,因此使用
docker compose ...而不是docker-compose。 oh-my-zshdocker和docker-compose插件在.zshrc中保持启用状态。 kind和minikube(来自 binstaller)使用 docker 驱动程序。直到您再次登录,docker需要sudo或newgrp docker。- 属于
docker组相当于拥有 root 访问权限。这是通常的权衡,同样的 旧的 podman-docker 套接字设置已完成。如果您想避免它,请考虑 Docker 的无根模式。 - 使用运行
docker run --rm hello-world的./bootstrap.sh --only post-checks进行检查。
使用 dotbot 的点文件
原始存储库是事实来源。 w0rxbend/system-bootstrap
被克隆到 ~/.system-bootstrap,dotbot 直接从该克隆链接出点文件。这个仓库没有保留
副本:dotfiles/ 仅保留原始存储库中没有同等内容的内容。
克隆人
scripts/system-bootstrap-sync.sh(dotfiles 的相 system-bootstrap-clone 或 just dotfiles-pull):
- 通过 https 克隆,因此它在任何 SSH 密钥存在之前就可以工作,并设置
remote.origin.pushurl = [email protected]:w0rxbend/system-bootstrap.git,因此一旦您拥有密钥,推送就会超过 SSH; - 当克隆存在时,仅快进它(
git fetch+git merge --ff-only)。本地提交,未提交 编辑、另一个分支、分离的 HEAD 或分歧的历史记录将被单独保留并带有警告;没有任何内容被重置, 隐藏或覆盖。不是该存储库克隆的路径是一个错误,不会被触及; - 当克隆已包含远程
HEAD时,--check(fluxion 探针)通过。它决定了第一次运行 和--re-probe运行;之后./bootstrap.sh跳过记录的步骤,因此更新克隆just dotfiles-pull.
两个 dotbot 配置
这里的 dotbot 是 Go 版本(dotbot-go v0.4.2、~/.apps/dotbot/bin/dotbot 或 Fluxion 已验证的缓存
复制)。 scripts/dotfiles-link.sh 每个配置运行一次,每个配置都有自己的基本目录:
| 配置(在此存储库中) | 基目录 | 友情链接 |
|---|---|---|
dotfiles/system-bootstrap.conf.yaml |
~/.system-bootstrap/.files |
~/.zshrc、~/.tmux.conf、~/.ideavimrc、~/.wezterm.lua、~/.hidden、~/.config/{starship.toml, alacritty/{alacritty,theme}.toml, kitty/kitty.conf, nvim, btop, ghostty, zathura/zathurarc, zellij/{config.kdl, layouts/*}, lazygit, lsd, yazi, bottom, nerd-fonts-installer/config.yaml}; ~/.config/paperwm/paperwm.conf 仅当安装 PaperWM 时 |
dotfiles/install.conf.yaml |
~/.ubuntu-bootstrap/dotfiles |
~/.custom.zsh、~/system-update.sh、~/.config/{,ubuntu-,gnome-}xdg-terminals.list(小猫)、~/.config/environment.d/90-session.conf、~/.config/binstaller/config.yaml(Ubuntu fork Fluxion适用,config/binstaller.yaml)和代理技能 链接 |
故意不与克隆链接:niri.conf.yaml 及其链接的所有内容(niri、DankMaterialShell、
danksearch、90-dms.conf、mimeapps.list、其 Alacritty xdg-terminals.list)、arch/ 和 fedora/(其
install.conf.yaml 和 *-system-update.sh),克隆的 binstaller 配置(~/.config/binstaller/config.yaml 链接
Fluxion应用的Ubuntu fork config/binstaller.yaml; tests/assertions/dotfiles.sh 报告任何版本引脚
与克隆的不同)和 vencord-settings-backup.json (手动导入)。 paperwm.conf 是 dconf dump; PaperWM之后
安装并链接后,用dconf load /org/gnome/shell/extensions/paperwm/ < ~/.config/paperwm/paperwm.conf加载。
链接默认值为 relink: true, create: true, force: true。在 dotbot 运行之前,dotfiles-link.sh 复制每个
链接目标处的 真实 文件或目录(以及指向其他地方的每个符号链接),其中 cp -a 为
~/.ubuntu-bootstrap-backup/,保持其相对于$HOME的路径(~/.zshrc ->
~/.ubuntu-bootstrap-backup/.zshrc、~/.claude/skills -> ~/.ubuntu-bootstrap-backup/.claude/skills)。一个年纪较大的
备份永远不会被覆盖;较新的不同副本具有 .YYYYmmdd-HHMMSS 后缀。 create: 给出明确的
模式(~/.vim/undo-history 为 0755 和 0700),因为 dotbot-go v0.4.2 否则会创建目录为 0777。
Ubuntu 上的 .zshrc : ~/.custom.zsh 覆盖
~/.zshrc 是克隆中的共享文件。它以 [-f ~/.custom.zsh ] && source ~/.custom.zsh 结尾,并且
dotfiles/custom.zsh 链接在那里。它带有以前在复制的版本中进行编辑的 Ubuntu 差异
.zshrc:~/.cargo/env、~/.local/bin 首先在 PATH(克劳德代码、Codex、uv、诗歌、星舰)、~/.kimi-code/bin、
pnpm 11's $PNPM_HOME/bin, ~/.apps/yq/bin, the oh-my-zsh ubuntu plugin (the shared plugin list has dnf), and
bootstrap / dotfiles 别名。所以老手编~/.zshrc放到PATH上的工具(claude、codex、kimi)
留在PATH; tests/assertions/dotfiles.sh 检查交互式 zsh 是否找到它们。
日常工作流程:在 ~/.system-bootstrap 中编辑并提交
nvim ~/.config/kitty/kitty.conf # the link points into ~/.system-bootstrap/.files
cd ~/.system-bootstrap && git add -p && git commit -m "kitty: ..." && git push # SSH pushurl
just dotfiles-pull # later, on any machine: fast-forward the clone
just dotfiles # re-link after adding a file or editing a dotbot config (idempotent)
just dotfiles-dry # preview (backups + dotbot -n)
just dotfiles-check # every link resolves to its source?
仅 Ubuntu 文件 (dotfiles/) 在此存储库中进行编辑和提交。一个新的共享点文件进入
~/.system-bootstrap/.files(在那里提交)加上 dotfiles/system-bootstrap.conf.yaml 中的 link: 行。运行
just dotfiles 现在链接它。 ./bootstrap.sh 也选择配置编辑:bootstrap.sh 导出两者的摘要
dotbot configs 和 scripts/dotfiles-link.sh (ZB_DOTFILES_INPUTS),链接项以它命名
(dotbot-links-<digest>)。 Fluxion 会从 --skip-already-installed 下的状态跳过记录项,并且不会
对配置进行指纹识别,因此,如果没有该配置,引导程序就永远不会链接已编辑的配置。新的摘要就是新的
item:当每个链接都正确时,它的探测器(dotfiles-link.sh --check)会跳过它,否则它会运行。
克隆步骤不同:一旦记录,./bootstrap.sh 就会从状态中跳过它,因此它不会快进
在以后的运行中克隆。使用 just dotfiles-pull(或 ./bootstrap.sh --only dotfiles --re-probe)。
~/.system-bootstrap/.files/.config/vesktop/vencord-settings-backup.json 是故意不链接的。它是一个
您手动导入的备份;请参阅下面的手动步骤。
代理技巧
我的代理技能存在于一个真实的 git-tracked 文件夹,dotfiles/agents/skills/,以及每个编码代理链接
对其(dotbot,dotfiles/install.conf.yaml):
| 链接 | 代理 | 当 |
|---|---|---|
~/.agents/skills |
Codex(本地读取)和共享位置 | 总是 |
~/.claude/skills |
克劳德·科德 | 总是 |
~/.cursor/skills, ~/.gemini/skills, ~/.copilot/skills, ~/.config/opencode/skills |
光标,双子座 CLI,副驾驶 CLI,开放代码 | 仅当该代理的目录存在时(dotbot if:) |
布局:每个技能一个文件夹,文件夹名称必须等于其 SKILL.md 前面内容中的 name:(
文件始终称为 SKILL.md)。 dotfiles/agents/skills/README.md 有详细信息和示例。
dotfiles/agents/skills/
├── README.md # not a skill (outside any skill folder)
├── .gitignore # ignores synced/ (Claude Code's own cache of claude.ai skills)
└── my-skill/
├── SKILL.md # ---nname: my-skillndescription: ...n---
└── scripts/ references/ # optional
验证循环(也由 tests/assertions/dotfiles.sh 运行):
cd ~/.ubuntu-bootstrap/dotfiles/agents/skills
for d in */; do d=${d%/}; [ "$d" = synced ] && continue
n=$(sed -n 's/^name:[[:space:]]*//p' "$d/SKILL.md" 2>/dev/null | head -n1 | tr -d ""'")
[ "$n" = "$d" ] && echo "ok $d" || echo "FAIL $d (name: '${n:-missing SKILL.md}')"; done
scripts/link-skills.sh(POSIX sh、just skills)在没有 dotbot 的情况下进行链接,例如在安装后
代理:它将 ~/.agents/skills 指向 repo 文件夹,并将 <agent>/skills 指向 ~/.agents/skills
ln -sfn,跳过未安装的代理,保留正确的链接,并且永远不会覆盖真实的链接
目录(它报告它并退出1;您自己将其移动到~/.ubuntu-bootstrap-backup/)。 --check 和 --dry-run
只报告。
注意事项:
- 第一次运行
dotfiles替换真实的~/.claude/skills目录,备份到后~/.ubuntu-bootstrap-backup/.claude/skills。它只保存了synced/,克劳德·科德的claude.ai技能的缓存,这 Claude Code 在链接文件夹内重新创建(git-ignored)。 - Codex 的捆绑技能(
~/.codex/skills/.system)从未被触及。~/.codex/skills/onboard-new-user不是 移动:它是 Codex 应用程序的首次运行入门技能(它调用仅限应用程序的工具,例如setup_codex_step),这不是我的技能,并且在其他特工中不起作用。
鼠尾草发射器
模块vicinae(profiles/75-vicinae.yaml,默认顺序,在gnome之后):
| 件 | 如何 |
|---|---|
| 野豌豆 v0.29.0 | 没有 .deb/PPA,并且发布的 tarball 是针对 Arch 的 Qt6 构建的。官方 AppImage(sha256 固定)通过固定到标签 v0.29.0(sha256 固定)的官方安装脚本提取到 /usr/local 中,使用 --appimage 和 TERM=dumb 以 root 身份运行(脚本中止,没有TERM)。作为 root,它还会在 vicinae-input-server 上设置 cap_dac_override 并加载 uinput(片段、粘贴)。探头为vicinae version = v0.29.0 |
| 服务器 | 安装程序附带的 systemd 用户 单元(/usr/local/lib/systemd/user/vicinae.service、vicinae server --replace、WantedBy=graphical-session.target)已启用并启动; vicinae ping 必须回答。 vicinae toggle 不自行启动服务器 |
| GNOME 扩展 | vicinae@dagimg-dot v1.7.2(EGO 8594,shell 46-50),GNOME Wayland 上需要用于剪贴板历史记录、窗口切换器、粘贴、居中和近距离焦点丢失。从固定的 GitHub 发行版 zip 安装到 ~/.local/share/gnome-shell/extensions/,编译模式,添加到 enabled-extensions,所有这些都没有 GNOME Shell 确认对话框。 下一个日志 out/in 后处于活动状态(session 检查点) |
Super+D |
运行 /usr/local/bin/vicinae toggle 的 GNOME 自定义快捷方式(Vicinae 自己的全局快捷方式需要 X11 或 ext-hotkey-v1,而 Mutter 缺乏)。 Ubuntu的模式覆盖(10_ubuntu-settings)将Super+D绑定到show-desktop,因此show-desktop首先设置为['<Primary><Super>d', '<Primary><Alt>d'](撤消:gsettings reset org.gnome.desktop.wm.keybindings show-desktop) |
重新登录后,按 Super+D 并立即键入:启动器应居中打开并聚焦(GNOME 的
focus-new-windows 为 smart)。不要从应用程序网格启动“Vicinae”:它的启动器运行
vicinae server --replace 并与 systemd 副本进行斗争。日志:journalctl --user -u vicinae。碰撞和撤销是
在配置文件标题中进行了描述。
测试
tests/ 在镜像生产 1:1 的测试配置文件上执行相同的编排 (bootstrap.sh):
tests/gen-test-profiles.sh从profiles/中的每个文件生成tests/generated/<same path>(python3 + PyYAML,tests/lib/gen_test_profiles.py)。唯一的变化:prompt-logout/requires-new-shell删除重新启动策略,删除interrupt/manual/shell-reload步骤(并且阶段留空, 及其dependsOn引用),confirm:防护被删除,相对config:路径变为绝对路径。 每个生成的文件都以注释开头,其中准确列出了更改的内容。今天是session注销 检查点和post-checks中的三个手动提醒。相同的列表转到tests/generated/production-only.tsv,prod-status阶段报告。tests/generated/是 git-ignored:它是派生数据,由bootstrap.sh --test重新生成,并且 每次使用之前的tests/run-tests.sh(如果--check过时,则会显示差异),因此它不会漂移。./bootstrap.sh --test ...运行状态名称为test-NAME的配置文件,因此生产状态 (~/.local/share/fluxion/NAME.state.json) 未受影响。
tests/run-tests.sh 阶段(全部默认,--stages a,b 可选择):
| 舞台 | 发生了什么 |
|---|---|
validate |
fluxion validate --strict + 每个选定测试配置文件的 lint,并且 bootstrap.sh --test --dry-run 退出 0,没有检查点 |
apply |
bootstrap.sh --test --only MODULES 每个模块退出 0 |
idempotency |
再次运行相同的操作:每个模块都退出 0,除了 assert 步骤之外没有任何运行(fluxion 会在每次运行时重新检查每个断言,并且从不跳过保持 1 的阶段,请参阅警告表)。 --strict-idempotency 添加了 --re-probe,因此记录的状态被忽略,并且每一项都必须由其实时探针满足;当它们的步骤没有 probeCommand 时,包 actions 也会运行,例如 apt update,并且也不被计算在内(这些配置文件中的每个 actions: [update] 都有一个,所以没有一个运行:00-base 在成功更新后跳过它 6 小时,一旦步骤的包是 10-apps安装); pipx、uv-tool、snap、npm-global 和 go-install 后端的 tool-packages 项目也没有步骤 probeCommand,因为 Fluxion 没有针对这些项目的实时探针(fluxion status 将它们显示为未知)并重新运行它们。自fluxion 0.4.0(提交9d7b731和82f3e77)以来,cargo/cargo-binstall crates和sdkman-packages候选者会按项目进行探测,因此必须跳过它们。再次运行的项目列在日志目录的 ran-again-MODULE.txt 中 |
prod-status |
只读,测试无法运行的内容:对于 production-only.tsv 中的每个仅生产部分,来自 生产 配置文件和状态 (fluxion status --format json) 的实时状态:done、PENDING 以及步骤自己的消息(用户的手动步骤;报告,未失败),或not exercised(注销检查点)。列于汇总表下方 |
assert |
tests/assertions/MODULE.sh:真正的结果。配置文件自己的列表中的软件包、固定版本的命令、apt 源和密钥环、docker/containerd 活动和 docker run --rm hello-world(使用 sudo -n 直到 docker 组处于活动状态)、~/.system-bootstrap 克隆和 Pushurl、每个 dotbot 链接解析为克隆或此存储库、技能链接 + 名称检查,交互式 zsh 查找 claude/codex/kimi、Super+1..9 的 gsettings(加上对任何其他持有者的扫描)、Super+D -> vicinae 和 show-desktop、vicinae 用户服务和 ping、/etc/group 中的登录 shell 和组成员身份 |
tests/run-tests.sh --list # modules, generated profiles, GUI needed?
tests/run-tests.sh --stages validate --with-optional # read-only (just test-validate)
tests/run-tests.sh --assert-only --only gnome,vicinae # read-only (just test-assert ...)
tests/run-tests.sh --only gnome,vicinae # apply + idempotency + assert for two modules
tests/run-tests.sh # the whole default sequence
tests/run-tests.sh --container # base,apps,toolchains,binaries,shell,dotfiles,wallpapers
# in a throwaway ubuntu:26.04 container (needs docker)
FLUXION_BIN=/path/to/fluxion tests/run-tests.sh --require-prod-bin ... # another build; fail if production differs
- Fluxion 由
scripts/lib/fluxion-bin.sh解析,与bootstrap.sh解析它完全相同($FLUXION_BIN,否则fluxion-bin.local,否则 PATH),因此绿色运行涵盖了生产二进制文件。运行打印二进制文件,其中 来自及其 binstaller 引脚,拒绝早于 0.4.1 的 Fluxion,并在出现错误时发出警告 显式FLUXION_BIN与普通./bootstrap.sh运行的不同(--require-prod-bin使得 失败)。容器模式安装相同的二进制文件。 - 从 GNOME 会话运行主机测试。如果没有会话总线(SSH、cron),则每次需要它的检查都会失败
而不是被跳过,因此
gnome、vicinae和gnome-extensions无法通过零检查;只有 容器会跳过它们。列表助手(assert_pkgs、assert_flatpaks、assert_snaps)在空列表上失败,因此 形状发生变化的轮廓不能空空通过。 tests/assertions/dotfiles.sh证明“没有副本”:tests/lib/find_copies.py比较此文件的每个 git-tracked 文件 存储库,其中包含克隆的.files下的每个 git-tracked 文件,逐字节并包含注释、引号和空格 正常化了。它还报告(跳过)Ubuntu 分支config/binstaller.yaml中的每个 binstaller 版本 pin 与克隆体不同。ASSERT_NETWORK=0跳过需要网络的检查(apt-get update,docker run,克隆的ls-remote)。ASSERT_LIVE_INPUT=1让gnome真正按下Super+3/Super+1(参见gnome)。- 日志、每阶段
--report文件和summary.tsv转到tests/logs/<timestamp>/(git-ignored;--log-dir改变)。 - 每个断言文件也单独运行:
tests/assertions/vicinae.sh。 - 容器模式是新鲜机测试。它构建了
tests/container/Dockerfile: ubuntu:26.04 以及软件包 在tests/container/ubuntu-baseline.txt中,所有这些都随 Ubuntu 26.04 Desktop 一起提供(对照 桌面映像安装的软件包列表,/var/log/apt/history.log的第一个条目在新的 26.04.1 上) 除快速启动安装的git和curl外;主机的用户名、uid 和主路径 无密码 sudo 仅在图像内。镜像保留Ubuntu自带的/etc/os-release(ID=ubuntu,VERSION_CODENAME=resolute)。 Desktop、snapd 和 flatpak 都不在里面。然后运行git clones 这个存储库的提交了 HEAD (以只读方式安装)~/.ubuntu-bootstrap,与快速启动完全相同,因此未测试未提交的更改(它警告)。只有 非GUI模块运行(base,apps,toolchains,binaries,shell,dotfiles,wallpapers);其他人都被拒绝。 - 容器中没有静默地跳过任何内容。需要 systemd 作为 PID 1 或 snapd 的步骤(
systemd-unit和system-setting种类,ghostty、code和crystal按扣;tests/lib/gen_test_profiles.py中的CONTAINER_SKIPS) 被删除 仅来自测试配置文件 (TEST_CONTEXT=container),每个配置文件都列在生成的文件的标头中, 在运行之前和摘要中的日志目录中的container-skips.tsv中。断言运行于ASSERT_CONTEXT=container并为每个需要 systemd、snapd 的检查打印skip行(带有原因), flatpak、GNOME 会话或 GUI 模块的输出(claude/codex/kimi 来自desktop-apps)。 post-checks持有断言,仅传入session模块之后启动的会话(docker group、Vicinae 扩展已加载)。在您注销并重新登录之前,其apply和idempotency阶段正是在这些方面失败;的 断言 (tests/assertions/post-checks.sh) 将它们视为信息性的。
添加或更改项目
将一个新项目放入其所属的模块中,使其保持在正确的阶段,然后验证:
| 添加 | 哪里 | 如何 |
|---|---|---|
| Ubuntu 归档包 | profiles/00-base.yaml |
将名称添加到匹配的 apt-* 阶段列表中。首先检查它是否存在:apt-cache policy NAME |
| 第三方apt应用程序 | profiles/10-apps.yaml |
新叶相 dependsOn: [host-check] 具有 apt-repository 步长(密钥的引脚 checksum:curl -fsSL KEY_URL | sha256sum) followed by an apt-packages步骤 |
| 一个扁平包装 | profiles/60-desktop-apps.yaml |
将完整应用程序 ID 添加到 flatpak-* 类别阶段(flatpak remote-info flathub ID 进行检查) |
| 啪啪啪 | profiles/60-desktop-apps.yaml,相snaps |
严格按扣:tool-packages 与 backend: snap。经典快照:带有 sudo: true、run: snap install NAME --classic 和 unless: snap list NAME 的 commands 项目 |
| 锈 CLI | profiles/30-toolchains.yaml,相rust-crates |
添加板条箱名称(使用cargo-binstall安装) |
~/.apps 中的发布二进制文件 |
config/binstaller.yaml |
添加binstaller条目(如果可能的话,引脚version + checksum),然后将其路径添加到profiles/40-binaries.yaml中的binaries-binstaller探针,将其bin目录添加到PATH(共享: ~/.system-bootstrap/.files/.zshrc;仅限 Ubuntu:dotfiles/custom.zsh),并检查 tests/assertions/binaries.sh |
| 书呆子字体 | config/nerd-fonts/0N-*.yaml 和 ~/.system-bootstrap/.files/.config/nerd-fonts-installer/config.yaml |
将其添加到批次中(每个批次保持在约 15 个系列以下:每批次固定 15 分钟超时)以及克隆中的完整列表(从那里提交并推送); tests/assertions/binaries.sh 检查两者是否一致 |
| curl/installer 脚本 | 拥有该工具的模块 | 首选 shell-scripts 和 url + sha256(如果需要 bash,则 + shell: bash)。否则,commands 项目带有 creates: 和 probeCommand,因此重新运行时会跳过它 |
| 共享点文件 | ~/.system-bootstrap/.files/ + dotfiles/system-bootstrap.conf.yaml |
在克隆中添加并提交文件(从那里推送),在此处添加 link: 条目,然后添加 just dotfiles |
| 仅限 Ubuntu 的点文件 | dotfiles/ + dotfiles/install.conf.yaml |
添加文件和 link: 条目,然后添加 just dotfiles |
| 代理技能 | dotfiles/agents/skills/<name>/SKILL.md |
前面的文件夹名称 = name:;提交它。每个代理都可以通过链接看到它 |
| GNOME 设置 | profiles/70-gnome.yaml |
将 gsettings set 行添加到脚本中,并在需要时扩展其 probeCommand |
现有配置文件遵循的规则:
- 步骤名称在所有配置文件中都是唯一的(使用模块作为前缀:
apps-...、docker-...)。 - 每个阶段都在
dependsOn中列出其真正的先决条件(至少host-check)。可能部分失败的列表位于 叶期(没有什么取决于它)与execution: { continueOnError: true }。 - Shell 文本不得包含
${...}配置文件变量;通过args:/env:传递它们并使用普通的$HOME。 - 任何需要root的东西都使用
sudo: true(fluxion调用sudo -n;bootstrap.sh保持票据温暖)。 tests/assertions/<module>.sh中每个模块都有后置条件;当你添加一些东西时扩展它们 很重要。测试配置文件会自行重新生成。- 一个全新的模块文件:将其添加到
bootstrap.sh中的DEFAULT_PROFILES(或OPTIONAL_PROFILES)中,添加tests/assertions/<module>.sh(函数assert_<module with _ for ->),复制host-check与任何现有配置文件相匹配,并为其赋予唯一的metadata.name。
然后检查一下:
just validate # or: scripts/validate-all.sh (prod + test profiles, scripts)
./bootstrap.sh --dry-run --only NAME # exact commands, no changes
tests/run-tests.sh --only NAME # apply + idempotency + assertions on the test profile
./bootstrap.sh --only NAME # apply
重运行和幂等性
-
bootstrap.sh始终与--skip-already-installed一起应用。当fluxion状态时会跳过一个项目 将其记录为成功,或者当其探测器报告其存在时。探头包括dpkg-query、flatpak info、snap list,文件存在检查和每一步的probeCommand。 -
以未更改的指纹完成的阶段(其配置的哈希值,包括委托的配置文件和 内联脚本)被完全跳过。当您在一个阶段中更改任何内容时,它会再次行走,但是
--skip-already-installed探测通过的每个项目仍然被跳过。对于带有粗略探针的步骤(binstaller、 Nerd Fonts)使用just refresh-binaries/just refresh-fonts,或者运行fluxion apply ... --phase NAME而无需--skip-already-installed. -
失败的阶段永远不会被记录为完成,因此下次运行会重试它。
-
每个模块都保留自己的状态:
fluxion state show docker # what was recorded fluxion state path docker # ~/.local/share/fluxion/docker.state.json fluxion state forget --profile docker --phase docker-engine # re-run one phase next time fluxion state reset docker --force # forget everything for the module (just state-reset docker) -
tests/run-tests.sh检查这一点是否真实:测试应用后,第二次运行必须报告0 ok · 0 failed每个模块(参见 测试)。 -
--re-probe忽略记录的状态并仅信任实时探针。删除某些内容后很有用 手。 -
运行一个模块:
./bootstrap.sh --only toolchains。失败后恢复:./bootstrap.sh --from shell。 -
要在没有包装器的情况下直接运行 Fluxion,请使用相同的状态名称并导出相同的 PATH (请参阅
bootstrap.sh):sudo -v && fluxion apply -c profiles/30-toolchains.yaml --profile toolchains --skip-already-installed
此处处理 Fluxion 警告
标记为 fixed in Fluxion 0.4.0 的行是 Fluxion 版本 的内容;其余的是 在配置文件中处理并仍然适用。
| 警告 | 这个仓库如何处理它 |
|---|---|
dotfiles-apply 已损坏:它通过了 --config,但 dotbot-go 只接受 -c (并且它需要一个配置,而这里需要两个基本目录) |
80-dotfiles 从 shell-scripts 步骤运行 scripts/dotfiles-link.sh:dotbot -d ~/.system-bootstrap/.files -c dotfiles/system-bootstrap.conf.yaml,然后 dotbot -d dotfiles -c dotfiles/install.conf.yaml,以 --check 作为探针 |
dotbot 配置不是 dotfiles 阶段指纹的一部分,并且记录的项目会从状态中跳过(0.3.1 及更高版本),因此编辑后的 dotbot 配置从未由 ./bootstrap.sh 链接 |
链接项名为 dotbot-links-<digest of both configs + dotfiles-link.sh>(ZB_DOTFILES_INPUTS,由 bootstrap.sh 导出),因此更改的输入会生成 --check 探针决定的新项 |
apt包探针总是说“未安装”:输出清理程序将dpkg-query -f='${Status}t${Version}'中的选项卡变成空格,因此探针永远不会看到install ok installed(在0.3.1和当前主版本中,src/fluxion/executor/probe.cr + redaction.cr) |
--skip-already-installed 仍然跳过已完成的阶段,并且已安装软件包的 apt-get install 没有任何变化。断言直接使用 dpkg-query 检查包。 tests/run-tests.sh --strict-idempotency 需要对此修复进行流变(在 fix/zorin-bootstrap 分支上完成,该分支还将每个 apt 列表批处理为一个 apt-get install 并探测 system-setting 项目) |
通过的 assert 步骤记录在状态 (0.3.1) 中,因此使用 --skip-already-installed 时,他们的阶段在下一次运行时被跳过,并且不会重新检查守卫 |
Fluxion 0.4.0 (af2c932) 中已修复:断言的传递永远不会从状态中存储或信任,并且保存断言的阶段永远不会被跳过(其其他步骤仍然从 state/probes 跳过)。配置文件保持简单的kind: assert步骤;在 0.3.1 中,仅在 --re-probe 下重新检查更改的主机 |
apt-repository 探针仅检查 .list 是否存在; gpg-key 仅探测密钥环路径是否存在 (0.3.1),因此 vendor/hand-written claude-desktop.list (signed-by=...asc) 或密钥环路径中的错误密钥被视为永久安装 |
Fluxion 0.4.0 中已修复(f992d37、5d19083):源文件必须等于声明的 source 行,并且其密钥环必须非空; gpg-key 密钥环必须准确保存声明的指纹。 apps 声明 apps-claude-desktop-key(指纹固定)+ apps-claude-desktop-repo,无采用步骤。在已有供应商 claude-desktop.list 的主机上使用 0.3.1,使用 --re-probe --only apps 运行一次修补版本 |
prompt-logout 阶段从未被记录为已完成,并且运行退出 0 (0.3.1):暂停阶段仅写入恢复点,因此每次运行都会重新运行 session 并再次要求注销,并且 bootstrap.sh 看到 rc 0 而不是检查点代码 75,因此--with-optional 重新登录之前,它会进入可选模块(包括后检查) |
Fluxion 0.4.0 中已修复(4254ceb、d699c4a):该阶段被记录为已完成,并且 apply 退出 75,因此 bootstrap.sh 在检查点停止一次,下一次运行会从状态跳过 session。没有运行任何内容(跳过每个项目或仅断言)的 prompt-logout 阶段根本不会询问,因此聚合主机上的 ./bootstrap.sh --re-probe 和 --only session,obs 运行到最后 |
步骤的 probeCommand 在每个项目之前重新运行 (0.3.1),因此一旦较早的脚本使其成立,该步骤的后续脚本就会被跳过(“跳过:已安装(探测)”),并且该步骤仍算作成功 |
Fluxion 0.4.0 (9a77b8f) 中已修复:每次应用整个步骤时,都会回答一次步骤的 probeCommand。无论哪种方式,配置文件都遵循一个规则:每个可观察状态一个步骤,并且每个步骤的探测仅当其所有脚本完成时才为真。根据先前步骤留下的内容来判断的工作会得到自己的步骤(vicinae-post-install) |
Flatpak 探针仅列出应用程序(flatpak list --app,0.3.1),但 OBS 插件(com.obsproject.Studio.Plugin.*)是运行时引用,因此安装后它们仍然显示为不存在,并且 --re-probe 会再次安装它们(对于 Flatpak 来说无操作,但报告为更改) |
Fluxion 0.4.0 (7430ef4) 中已修复:探针列出了每个已安装的参考。在 0.3.1 中,默认的(基于状态的)幂等性运行仍然会跳过它们;只有 obs 上的 --strict-idempotency 报告它们再次运行。 assert_flatpaks 检查每个参考,而不仅仅是应用程序 |
gpg-key 在新帐户上失败:它使用 gpg --batch --no-options --show-keys 读取每个密钥,并且使用 --no-options gpg 不会创建丢失的 ~/.gnupg (gpg: Fatal: ~/.gnupg: directory does not exist!),因此在新安装时,每个 gpg-key 步骤都会失败(每个版本;通过容器测试发现) |
apps 在其 gnupg-home 阶段创建 ~/.gnupg (0700),三个 gpg-key 阶段所依赖的 |
fluxion 从不提示输入 sudo:它只使用 sudo -n |
bootstrap.sh 运行 sudo -v 一次,然后保持活动循环运行直到退出。 Ubuntu的sudo票持续15分钟而TeX Live单独运行需要更长的时间 |
| PATH 在启动时读取一次 | 每个模块一个 Fluxion 进程,并且 bootstrap.sh 预先导出所有未来的工具目录,因此后面的模块可以看到较早的安装 |
when: 在加载时评估 |
配置文件不在同一运行安装的工具上使用 commandExists 防护 |
SDKMAN 的安装程序需要 bash,但 toolchain 类型使用 sh |
SDKMAN、nvm 和 pyenv 将 shell-scripts 与 url、sha256 和 shell: bash 一起使用 |
| 失败的阶段会阻止依赖于它的一切 | dependsOn 仅列出真正的先决条件,脆弱列表位于叶阶段,列表阶段使用 continueOnError: true |
${...} 在 shell 文本中被拒绝 |
脚本使用普通 $HOME 并通过 args/env 获取配置文件值 |
apt-repository/gpg-key 永远亲爱的 |
每个密钥环路径均以 .gpg 结尾。 .asc 路径最终会保存二进制数据并破坏 apt |
prompt-logout 停止运行(也在空运行中) |
仅出现在最后一个模块session中;生成的测试配置文件将其丢弃 |
gext install 弹出 GNOME Shell 确认对话框(D-Bus 后端)并阻止运行 |
gnome-extensions 使用 gext -F install(文件系统后端); Vicinae 的扩展件是从固定拉链中解开的。探针检查文件+ enabled-extensions,因为gnome-extensions info仅在重新登录后才知道新扩展名 |
无 DEBIAN_FRONTEND |
Debconf 是为 mscorefonts 和wireshark 预置的 |
| 当上游脚本更改时,校验和引脚会失效 | 由于摘要不匹配,运行严重失败。重新计算引脚(请参阅 更新) |
引导后的手动步骤
- 在
session检查点之后注销并重新登录(或重新启动)。在那之前你并不在docker中,libvirt和kvm组(使用sudo docker ...或newgrp docker),新终端仍然启动旧终端 登录外壳。如果session失败,请使用chsh -s /usr/bin/zsh手动换壳。然后运行./bootstrap.sh --only post-checks.
./bootstrap.sh --only post-checks 提醒您接下来的三个:每个都是一个 manual 步骤,其探针通过一次
你已经完成了,直到那时模块退出1并打印指令(所以失败的post-checks正确
重新登录后通常意味着只打开一个提醒)。 tests/run-tests.sh 将它们列在“仅限生产”下
零件”与 done / PENDING。
-
GitHub CLI:运行
gh auth login。 -
SSH 密钥:运行
ssh-keygen -t ed25519 -C "[email protected]",然后运行gh ssh-key add ~/.ssh/id_ed25519.pub。 切勿将~/.ssh复制到此存储库中;.gitignore区块id_*、*.pem和*.key。 -
Flatpak 重复: 引导程序将 TG 平台、Zulip、Vesktop 和 Spotify 安装为 snaps。如果较旧的运行 把他们的扁平包装留在后面,用
flatpak uninstall org.telegram.desktop org.zulip.Zulip dev.vencord.Vesktop com.spotify.Client. -
登录到 1Password、Claude Desktop、ChatGPT、Claude 代码 (
claude)、Codex (codex)、Kimi (kimi)、VS 代码设置同步、Spotify、Discord/Vesktop 和 TG 平台。 -
Vesktop: 打开 Vencord 设置,转到备份和恢复,然后导入
~/.system-bootstrap/.files/.config/vesktop/vencord-settings-backup.json. -
Brave“GitHub”网络应用程序:在 Brave 中,打开 github.com,然后转到菜单 → 投射、保存和共享 → 将页面安装为 应用程序。浏览器自己创建这些网络应用程序,因此无法以任何合理的方式编写脚本。
-
区域格式: en_GB 格式和 A4 纸在设置→区域和语言中设置,其中写入
~/.pam_environment。再次将它们放在那里;该文件不在这里管理。 -
Claude 钥匙圈
.asc:保留它。claude-desktop软件包重写 每次升级时都会出现/usr/share/keyrings/claude-desktop-archive-keyring.asc,因此删除它不会产生任何效果。它是 无害:由apps编写的claude-desktop.list没有包标记,因此包将其指向 亲爱的.gpg。 -
可选:1Password debsig 策略。 Ubuntu 的 dpkg 仅在
debsig-verify为时强制执行包签名 设置。要启用 1Password 验证:sudo apt install -y debsig-verify sudo mkdir -p /etc/debsig/policies/AC2D62742012EA22 /usr/share/debsig/keyrings/AC2D62742012EA22 curl -sS https://downloads.1password.com/linux/debian/debsig/1password.pol | sudo tee /etc/debsig/policies/AC2D62742012EA22/1password.pol >/dev/null curl -sS https://downloads.1password.com/linux/keys/1password.asc | sudo gpg --dearmor --output /usr/share/debsig/keyrings/AC2D62742012EA22/debsig.gpg -
Neovim: 启动
nvim一次,以便 lazy.nvim 安装lazy-lock.json中列出的插件。 -
tmux:
dotfiles已安装插件。在 tmux 内部,prefix + I重新安装它们。 -
droidcam 别名: 它需要
scrcpy2.2 或更高版本,引导程序不会安装。 -
地址:重新登录后按
Super+D并立即输入;启动器应以居中方式打开 keyboard focus.gnome-extensions info vicinae@dagimg-dotshould now say ACTIVE (clipboard history needs it). -
备份: dotbot 替换的任何内容都位于
~/.ubuntu-bootstrap-backup/中(与$HOME中的路径相同)。删除它 once you are happy.
可选模块
./bootstrap.sh --only obs # OBS Studio + 10 plugins (flatpak)
./bootstrap.sh --only gnome-extensions # gext -F + 6 extensions (run in the GNOME session)
./bootstrap.sh --only wallpapers # ~109 MB of wallpapers from the old repo
./bootstrap.sh --only post-checks # after re-login
obs:大多数插件都是OBS flatpak扩展。该模块安装 flatpak 和 Flathub 遥控器本身 当desktop-apps尚未运行时。gnome-extensions:dash-to-dock(Ubuntu Dock 已经是其中之一)、tilingshell(Ubuntu 附带了 tiling-assistant)和 appindicator/status-icons(Ubuntu 附带 ubuntu-appindicators)被故意省略。所有六个都有 GNOME 50 构建。gext -F install解压各个扩展 并将其添加到enabled-extensions,而不显示普通gext install显示的 GNOME Shell 确认对话框。 之后注销并重新登录:Wayland 上的 GNOME Shell 仅在登录时加载新扩展。wallpapers:图像不在此存储库中。
没有移植,为什么
| 项目 | 原因 |
|---|---|
niri、DankMaterialShell/dms/danksearch、PaperWM 本身、sway、waybar、fuzzel、rofi、hypr*、COSMIC/SDDM 调整、multibg-wayland 箱、assets/icons、niri.conf.yaml |
平铺和拱形桌面设置。 Ubuntu 保留自己的 GNOME 桌面。 (paperwm.conf 仍从克隆链接,但前提是您自己安装 PaperWM) |
| dash-to-dock、tilingshell 扩展 | Ubuntu Dock 已经支持 Dash-to-Dock,并且 Ubuntu 还提供了平铺助手;平铺超出范围 |
| podman、podman-docker、工具箱、buildah | 替换为 Docker CE 和 distrobox |
RPM Fusion、ffmpeg 交换、fedora-workstation-repositories、Fedora/Arch dotbot 覆盖、fedora-/arch-system-update.sh |
仅适用于 Fedora 或 Arch。 Ubuntu的ubuntu-restricted-extras覆盖了编解码器,ubuntu-system-update.sh替换了更新脚本 |
| 勇敢的平包 | 勇敢来自于它在这个主机上的快照 |
dev.zed.Zed 扁平包装 |
Zed 来自 zed.dev/install.sh,与主机上一样 |
org.telegram.desktop、org.zulip.Zulip、dev.vencord.Vesktop、com.spotify.Client 平板包装 |
他们的快照被使用,就像在这个主机上一样 |
com.oguzhaninan.Stacer 扁平包装 |
从 Flathub 中删除。 Stacer 来自 apt 相反 |
apt kitty, neovim (0.9.5), yq (Python flavour), fd-find, gnome-shell-extension-manager |
替换为上游 kitty、binstaller 的 neovim 和 mikefarah yq、cargo 的 fd 以及 Extension Manager flatpak |
mimeapps.list |
只有 niri 配置在旧存储库中链接它,并且 Ubuntu/GNOME 管理它 |
coursier、platformio、deno、nimble、JetBrains 工具箱、Android SDK、opencode、mill、envman、~/.fzf.zsh、scrcpy |
由旧的 .zshrc 引用,但没有安装它们,并且它们不会出现在主机历史记录中。 .zshrc 线路留在防护装置后面,因此稍后安装任何一条线路都可以 |
| 自动 1Password debsig 策略 | Ubuntu 上的 dpkg 不会强制执行,除非您设置了 debsig-verify(请参阅手动步骤) |
| 旧存储库的格式为 CI(shfmt、stylua、prettier,...) | Fluxion validate/lint 与 scripts/validate-all.sh 一起是这里的质量门 |
更新中
日常:运行 update(~/system-update.sh 的 zsh 别名)或 just update。它更新 apt、snap、flatpak、
rustup, juliaup, SDKMAN, nvm/Node LTS, mamba, uv, pnpm, Poetry, oh-my-zsh and, optionally, the cargo crates. Each section
当工具丢失时会被跳过,并且一次失败不会停止其余的操作。
~/.apps 二进制文件和 Nerd 字体: ./bootstrap.sh --only binaries 不会刷新它们。 bootstrap.sh
总是通过 --skip-already-installed,并且在该模式下,fluxion 会跳过探针通过的项目,即使当
阶段的配置发生了变化。一旦所有 13 个可执行文件存在,binstaller 探针就会通过,并且每个字体探针都会通过
一旦 fc-list 找到它的家人。运行没有该标志的阶段(不需要 sudo):
just refresh-binaries # fluxion apply -c profiles/40-binaries.yaml --profile binaries --phase binstaller --no-tui
just refresh-fonts # ... --phase fonts-core,fonts-more,fonts-rest,fonts-noto --no-tui
因此,要修改工具,请在 config/binstaller.yaml 中编辑其版本(和校验和),然后运行 just refresh-binaries。
latest-url 工具(minikube、xplr、kubectl、neovide、neovim、yq)在每次刷新时都会迁移到最新版本。
撞针(安装程序脚本、密钥、tarball)。大多数远程脚本和密钥由 sha256 和 git 固定 按提交回购。当上游更改它们时,fluxion 会因摘要不匹配而失败,这是预期的。撞针:
curl -fsSL https://sh.rustup.rs | sha256sum # installer scripts / keys / descriptors
git ls-remote https://github.com/tmux-plugins/tpm HEAD # git-repo refs (40-hex)
然后编辑配置文件中的值并运行 just validate。
| 销 | 文件 |
|---|---|
Go 版本和 tarball sha256 (spec.vars)。 另外更改 go-toolchain probeCommand 中的文字 go1.27.1 :探针无法使用 ${...},并且每次运行都会重新下载过时的探针 |
profiles/30-toolchains.yaml |
| rustup, cargo-binstall script (commit and sha), SDKMAN, nvm tag and sha, pyenv, juliaup | profiles/30-toolchains.yaml |
| oh-my-zsh 修订版和 sha、zsh 插件提交、TPM 提交 | profiles/50-shell.yaml |
| Docker / GitHub CLI / Claude 桌面密钥 sha256; 1密码密钥指纹 | profiles/20-docker.yaml, profiles/10-apps.yaml |
distrobox 版本和 tarball sha256 (spec.vars)。 另外更改 docker-distrobox probeCommand 中的文字 distrobox: 1.8.2.5 |
profiles/20-docker.yaml |
| Flathub 描述符 sha256 | profiles/60-desktop-apps.yaml, profiles/optional/obs.yaml |
| binstaller 工具版本 | config/binstaller.yaml |
| Vicinae 版本、AppImage 和安装脚本 sha256、GNOME 扩展 zip 版本和 sha256(也是探针中的文字版本) | profiles/75-vicinae.yaml |
| 流动本身 | FLUXION_VERSION 位于 bootstrap.sh 中(一旦存储库依赖于新版本,FLUXION_MIN_VERSION 位于 scripts/lib/fluxion-bin.sh 中);如果 fluxion-bin.local 指向较旧的版本,请删除它。在修改之前请阅读 Fluxion 变更日志,因为上面的警告与版本相关 |
故障排除
查找失败的原因:
./bootstrap.sh --failed --only docker # missing / failed items (just failed docker)
fluxion explain -c profiles/20-docker.yaml --profile docker --phase docker-engine
fluxion status -c profiles/20-docker.yaml --profile docker --failed
fluxion state show docker # ~/.local/share/fluxion/docker.state.json
./bootstrap.sh --only docker --show-output --no-tui # re-run, echoing each command's output
apt-get update 失败并显示 crystal ... does not have a Release file(退出 100): Crystal 安装程序是
通过管道传输到 sudo zsh。 zsh 保留 ${OBS_PROJECT//:/:/} 的反斜杠,因此
/etc/apt/sources.list.d/crystal.list 包含 devel:/languages:/crystal(404)和
/etc/apt/trusted.gpg.d/devel_languages_crystal.gpg 为空。 base 首先将两个文件移动到 /var/backups(阶段
apt-sources-repair);水晶本身来自 crystal 按扣。手动修复它:
sudo rm -f /etc/apt/sources.list.d/crystal.list /etc/apt/trusted.gpg.d/devel_languages_crystal.gpg。如果你使用
再次安装该安装程序,将其通过管道传输到 bash,而不是 zsh,或者更好地使用 sudo snap install crystal --classic。
yazi 停在 Press <Enter> to continue with preset settings(TOML parse error ... "$schema" 或 missing field group): 从 ~/.system-bootstrap/.files/.config/yazi 链接的 yazi.toml 和 keymap.toml 是固定 yazi 的 v26 之前的格式v26.5.6 拒绝(旧的仓库固定相同的版本,所以这不是新的)。这是克隆的内容,因此请修复它(删除 "$schema" 行并将文件移至 v26 格式,然后以 ~/.system-bootstrap 提交); tests/assertions/dotfiles.sh 将其报告为跳过,直到加载链接的配置。
模块显示 ok 但未安装任何内容: 使用 --tui,在选择器处按 q 退出该模块,
Fluxion 退出 0。在没有 --tui 的情况下重新运行它。
“需要密码”/ sudo 失败: keep-alive 循环停止,例如因为 终端关闭或机器暂停。重新运行模块,完成的项目将被跳过。
Flatpak 安装失败并出现授权错误: 您可能正在 SSH 上运行,或者在活动范围之外运行
本地会话。从 GNOME 会话中的终端重新运行 ./bootstrap.sh --only desktop-apps。
gnome 失败其 gnome-session-check: 相同的原因:gsettings 需要 DBUS_SESSION_BUS_ADDRESS,这
只有本地会话有。
apt 或 dpkg 挂起,或者出现 debconf 问题: 软件包询问了未预置的内容。完成它
手与sudo dpkg --configure -a,添加debconf-set-selections线到base-debconf-preseed
profiles/00-base.yaml,并重新运行。
已持有 dpkg 锁: GNOME 软件或无人值守升级正在运行。等待,或检查
sudo lsof /var/lib/dpkg/lock-frontend,然后重新运行。
v4l2loopback DKMS 构建失败: 该模块必须针对正在运行的 HWE 内核(目前为 7.0)进行构建。
检查是否安装了 linux-headers-$(uname -r) 并查看 sudo dkms status。安全启动可能会要求您
在下次启动时注册 MOK 密钥。这里的故障仅影响 apt-media 阶段。
docker: permission denied ... docker.sock: docker 组仅在您注销并重新登录后适用。
当前 shell,使用 newgrp docker。
session模块失败,没有注销提示:添加组失败,通常是因为docker
未安装且 docker 组不存在。先修复./bootstrap.sh --only docker,然后运行
./bootstrap.sh --only session.
~/.system-bootstrap 中的 git status 显示 .files/.zshrc 中的更改: 安装程序在 dotbot 之后运行,并且
附加到链接文件。检查 git -C ~/.system-bootstrap diff .files/.zshrc。移动你想保留的东西
进入 dotfiles/custom.zsh (仅限 Ubuntu)或将其提交到克隆(共享)中,并丢弃其余部分
git -C ~/.system-bootstrap checkout .files/.zshrc。 system-bootstrap-sync.sh 永远不会覆盖此类编辑:
会触及他们的快进会被拒绝并发出警告。
dotfiles 失败,并显示“~/.system-bootstrap 存在,但不是 git 克隆”(或另一个存储库的克隆): 移动该文件
删除目录并重新运行 ./bootstrap.sh --only dotfiles;脚本永远不会删除它。
Super+1..9 不执行任何操作: 其他东西仍然会获取密钥。 tests/assertions/gnome.sh 列出每个 gsettings
持有钥匙Super+N;通常的罪魁祸首是重置或升级后 Ubuntu Dock 的 hot-keys=true(dash-to-dock)。重新运行
./bootstrap.sh --only gnome.
Super+D 仍然显示桌面/不执行任何操作: 检查 gsettings get org.gnome.desktop.wm.keybindings show-desktop (must not contain <Super>d) and systemctl --用户状态 vicinae (vicinae 切换需要
服务器)。 tests/assertions/vicinae.sh 全部检查。
tool-packages 表示其后端丢失(cargo-binstall、pipx,...):fluxion 在没有
导出PATH。始终通过 ./bootstrap.sh 或 just。
bootstrap.sh 停止于“是 Fluxion X;此存储库需要 0.4.1 或更高版本”:它解决了旧的 Fluxion(来自
fluxion-bin.local 或 ~/.local/bin)。如果 fluxion-bin.local 指向旧版本,请删除它,然后安装
发布为 Fluxion 版本;当 ./bootstrap.sh 发现根本没有通量时,它会自行执行此操作。
校验和或摘要不匹配:上游安装程序已更改。验证新文件并更新引脚(请参阅 正在更新)。
配置文件因无效而被拒绝(退出 3): 运行 just validate 立即查看每个错误及其错误
YAML 路径。
旧仓库:w0rxbend/system-bootstrap · Fluxion 文档:https://worxbend.github.io/fluxion.cr/
相关文章
- nk-design:实践指南 10-02
- intent-verify:AI Agent 工具实践指南 10-02
- ubuntu-bootstrap:实践指南 10-02
- euparliamentmonitor:AI Agent 工具实践指南 10-02
- clueless:AI Agent 工具实践指南 10-02
- riksdagsmonitor:AI Agent 工具实践指南 10-02