[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-82016":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":14,"stars30d":13,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":19,"hasPages":19,"topics":21,"createdAt":10,"pushedAt":10,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":16,"starSnapshotCount":16,"syncStatus":25,"lastSyncTime":26,"discoverSource":27},82016,"knuckle","projectbluefin\u002Fknuckle","projectbluefin","Deploy Flatcar Container Linux \u002F Core OS at home with a familiar UX","",null,"Go",33,8,1,10,0,44.16,"Apache License 2.0",false,"main",[],"2026-06-11 04:07:44","# Knuckle\n\n[![codecov](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fprojectbluefin\u002Fknuckle\u002Fgraph\u002Fbadge.svg)](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fprojectbluefin\u002Fknuckle) [![Go Report Card](https:\u002F\u002Fgoreportcard.com\u002Fbadge\u002Fgithub.com\u002Fprojectbluefin\u002Fknuckle)](https:\u002F\u002Fgoreportcard.com\u002Freport\u002Fgithub.com\u002Fprojectbluefin\u002Fknuckle)\n\nA modern, interactive TUI \"installer\" for [Flatcar Container Linux](https:\u002F\u002Fwww.flatcar.org\u002F), designed for bare-metal deployments. Not a real installer because making one would be dumb. There's no reason to make a \"Bluefin Server\" if Bluefin just gives you a nice tool to use Flatcar. But also it's just an ignition thing, so let's **UNIFY COREOS AND FLATCAR INSTALLATION** and share one installer and tests.\n\nKnuckle is a charm.sh form that makes a valid ignition file and passes it to the Flatcar installer. We're just making users not have to use ignition, with an ubuntu-server style install UX. \n\nThis is also basically [Azure Container Linux (Home Edition)](https:\u002F\u002Fopensource.microsoft.com\u002Fblog\u002F2026\u002F05\u002F18\u002Ffrom-open-source-to-agentic-systems-microsoft-at-open-source-summit-north-america-2026\u002F). \n- [Download an ISO](https:\u002F\u002Fgithub.com\u002Fprojectbluefin\u002Fknuckle\u002Freleases) for ARM or AMD64 and install it.\n- Follow the installer you'll be left with a pristine upstream install of Flatcar linux\n- This is early and prealpha, all feedback and contributions welcome!\n\n![img](https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F802bb450-f48c-4186-a1d0-542535124bc5)\n\n> [!WARNING]\n> **Pre-alpha software — use with caution**\n> - **Wipes the target disk** — the installer is destructive with no undo after confirmation\n> - **UEFI-only** — BIOS\u002Flegacy boot is not supported\n> - **Single disk only** — multi-disk setups are not supported\n> - **English only** — no i18n support yet\n\n## Installation\n\n> Knuckle is pre-alpha. Test on hardware you can reinstall.\n\n### 1. Download the installer ISO\n\nFrom [Releases](https:\u002F\u002Fgithub.com\u002Fprojectbluefin\u002Fknuckle\u002Freleases), download:\n\n| Architecture | Release asset |\n|---|---|\n| AMD64 \u002F x86_64 | `knuckle-installer-stable-amd64.iso` |\n| ARM64 | `knuckle-installer-stable-arm64.iso` |\n\nVerify the checksum (recommended):\n\n```bash\n# use the matching .sha256 file for your architecture\nsha256sum -c knuckle-installer-stable-amd64.iso.sha256\n```\n\n### 2. Write the ISO to USB\n\nLinux:\n\n```bash\n# Replace \u002Fdev\u002FsdX with your USB device (check with lsblk first)\nsudo dd if=knuckle-installer-stable-amd64.iso of=\u002Fdev\u002FsdX bs=4M status=progress conv=fsync\n```\n\nmacOS: use `diskutil list` to find your USB device and write with `dd` using the matching `\u002Fdev\u002FdiskN` path.\n\nWindows: use [Rufus](https:\u002F\u002Frufus.ie), select the ISO, choose **DD Image** mode, then start.\n\n### 3. Boot from USB\n\n1. Insert the USB drive into the target machine.\n2. Enter BIOS\u002FUEFI setup (commonly `F2`, `F12`, or `Del` at power-on).\n3. Set USB as first boot device, or pick it from the one-time boot menu.\n4. Save and reboot; Knuckle starts automatically.\n\n### 4. Follow the wizard\n\nThe base flow is 9 steps:\n\n1. **Welcome** (`Ctrl+A` toggles external Ignition URL mode)\n2. **Network** (DHCP or static IPv4)\n3. **Storage** (select target disk; all data is erased)\n4. **User** (hostname, timezone, password, SSH keys)\n5. **Sysext** (optional Flatcar Bakery extensions)\n6. **Update strategy**\n7. **Review** (`Ctrl+B` toggles full Butane preview)\n8. **Install** (`flatcar-install` runs with live progress)\n9. **Done** (remove USB and reboot)\n\nIf you enable Tailscale or NVIDIA options, additional wizard steps appear.\n\n### 5. First boot\n\nSSH to the installed system with the credentials you configured:\n\n```bash\nssh core@\u003Cyour-server-ip>\n```\n\nFor unattended installs, see [docs\u002FHEADLESS-CONFIG.md](docs\u002FHEADLESS-CONFIG.md).\n\n## Why\n\nAnother Linux for the home? Flatcar is in the [CNCF](https:\u002F\u002Fcncf.io), which means there's a core operating system in a vendor-neutral Foundation. The kind of tech that will stick around in the long term. And designed to run anything you want. Plop anything from [linuxserver.io](https:\u002F\u002Fwww.linuxserver.io\u002F) right on it for an awesome setup. \n\nPerfect for home servers, NAS builds, k8s cluster setups, you name it. The [Flatcar Bakery](https:\u002F\u002Fflatcar.github.io\u002Fsysext-bakery\u002F) is included, allowing for endless extensibility:\n\n![sysexts](https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F86f0c439-4c27-4c04-a2fc-880d499f7c28)\n![progress](https:\u002F\u002Fgithub.com\u002Fuser-attachments\u002Fassets\u002F0d4160da-8731-4a92-b103-98b901dd9c3d)\n\n\n## Features\n\n- **Up to 11-step guided wizard** — Welcome → Network → Storage → User → Sysext → [Nvidia] → [Tailscale] → Update Strategy → Review → Install → Done (Nvidia and Tailscale steps are conditional on sysext selection)\n- **Channel selector with version details** — shows kernel, systemd, docker, containerd, ignition, and etcd versions per channel (sourced from SBOM JSON, `version.txt`, package lists, and `rootfs-included-sysexts`)\n- **Hardware probing** — automatic disk and network interface discovery with `\u002Fdev\u002Fdisk\u002Fby-id` path resolution\n- **Network configuration** — DHCP or static IPv4\n- **User setup** — hostname, timezone, password (bcrypt hashed), GitHub SSH key fetching with multi-key support, local `~\u002F.ssh\u002F*.pub` auto-detection\n- **System extensions** — architecture-aware sysext catalog fetched via TLS from [flatcar\u002Fsysext-bakery](https:\u002F\u002Fgithub.com\u002Fflatcar\u002Fsysext-bakery) GitHub Releases API (not yet cryptographically verified — see [docs\u002FSECURITY.md](docs\u002FSECURITY.md))\n- **NVIDIA driver series** — conditional step shown when `nvidia-runtime` sysext is selected; selects the kernel driver series (e.g. `550`, `560`) matching the chosen NVIDIA runtime sysext; supported in both TUI and headless (`nvidiaDriverSeries`) modes\n- **Tailscale provisioning** — conditional step shown when `tailscale` sysext is selected; sets a pre-auth key (`tskey-auth-…`) written to `\u002Fetc\u002Ftailscale\u002Ftailscale.env`; supported in both TUI and headless (`tailscaleAuthKey`) modes\n- **Update strategy** — reboot, off, or etcd-lock options\n- **Review screen** — full Butane YAML preview before install\n- **Install step** — progress bar, wipes stale disk signatures, runs `flatcar-install`, then relocates the backup GPT header for larger target disks\n- **Ignition generation** — produces valid Ignition JSON via in-process Butane compilation (Flatcar variant, no CLI dependency)\n- **Headless mode** — `--headless --config \u003Cfile.json>` for automated installs (CI\u002FCD friendly)\n- **Installer ISO** — UEFI-bootable ISO with systemd-boot (amd64 + arm64), with `systemd.gpt_auto=0` set in both boot entries to avoid GPT auto-generator hangs when the ISO is written to larger USB media\n- **Config validation** — consistency checks before install\n- **Swap file** — 4 GiB `\u002Fvar\u002Fswapfile` provisioned by default; configurable size (up to 32 GiB) or disabled via headless config\n- **Dry-run mode** — `--dry-run` flag skips all disk writes\n- **Ctrl+C double-press** — confirmation before quitting\n\n## Support Matrix\n\n| Dimension | Supported |\n|---|---|\n| Architecture | x86_64, ARM64 |\n| Storage | Single target disk |\n| Networking | DHCP, static IPv4 |\n| Language | English |\n| Sysexts | Official Flatcar Bakery (via GitHub Releases API, arch-aware) |\n| Config mode | Guided OR external Ignition URL (`Ctrl+A`) — mutually exclusive |\n\n## Keyboard Shortcuts\n\n- `Ctrl+A` on the Welcome step — toggle external Ignition URL mode\n- `Ctrl+B` on the Review step — toggle the Butane YAML preview\n- `Ctrl+C` × 2 — quit with confirmation\n\n## Quick Start\n\n```bash\n# Build from source (amd64)\njust build\n\n# Cross-compile for arm64\njust build-arm64\n\n# Run the installer (on a Flatcar live environment)\n.\u002Fbin\u002Fknuckle\n\n# Dry-run mode (no disk writes)\n.\u002Fbin\u002Fknuckle --dry-run\n\n# Headless install from JSON config\n.\u002Fbin\u002Fknuckle --headless --config install.json\n\n# Pin to a specific Flatcar release\n.\u002Fbin\u002Fknuckle --channel beta --flatcar-version 3975.2.1\n```\n\n## CLI Flags\n\n| Flag | Default | Description |\n|---|---|---|\n| `--dry-run` | false | Simulate install — no disk writes |\n| `--headless` | false | Non-interactive mode; requires `--config` |\n| `--config \u003Cfile.json>` | — | Path to JSON config for headless installs |\n| `--channel \u003Cname>` | stable | Flatcar release channel: `stable`, `beta`, `alpha`, `lts`, `edge` |\n| `--flatcar-version \u003Cver>` | — | Pin to a specific Flatcar version (e.g. `3510.2.8`); omit to use latest |\n| `--log-file \u003Cpath>` | `\u002Ftmp\u002Fknuckle.log` | Path to structured log file (`slog`); stdout is reserved for the TUI |\n| `--demo` | false | Mock hardware and catalog data — no network, no real disks; for UI demos and screen recording |\n| `--version` | — | Print version and exit |\n\n## Environment Variables\n\n| Variable | Example | Effect |\n|---|---|---|\n| `KNUCKLE_ARCH` | `KNUCKLE_ARCH=arm64 just vm` | Overrides the default `amd64` target used by `just` recipes so builds, ISO tasks, and VM workflows target arm64 instead. Useful for ARM64 cross-builds and VM testing. |\n| `KNUCKLE_TEST_MAIN` | `KNUCKLE_TEST_MAIN=1 go test .\u002Fcmd\u002Fknuckle` | Internal test helper used by `cmd\u002Fknuckle\u002Fmain_test.go` to re-enter `main()` inside the compiled test binary, so flag-validation and early-exit paths can be exercised without launching the TUI. |\n\n## Headless Mode\n\n`--headless --config \u003Cfile.json>` drives the same install path as the TUI without any user interaction. Useful for CI\u002FCD, automated bare-metal provisioning, and scripted lab setups.\n\nMinimal example (`install.json`):\n\n```json\n{\n  \"hostname\": \"flatcar-01\",\n  \"channel\": \"stable\",\n  \"disk\": \"\u002Fdev\u002Fdisk\u002Fby-id\u002Fata-SomeSeagate_1TB\",\n  \"network\": {\"mode\": \"dhcp\"},\n  \"users\": [\n    {\"username\": \"core\", \"ssh_keys\": [\"ssh-ed25519 AAAA...\"]}\n  ],\n  \"update_strategy\": \"reboot\"\n}\n```\n\nSwap is **enabled by default** (4 GiB `\u002Fvar\u002Fswapfile`). To customise:\n\n```json\n{\n  \"hostname\": \"flatcar-01\",\n  \"channel\": \"stable\",\n  \"disk\": \"\u002Fdev\u002Fdisk\u002Fby-id\u002Fata-SomeSeagate_1TB\",\n  \"network\": {\"mode\": \"dhcp\"},\n  \"users\": [\n    {\"username\": \"core\", \"ssh_keys\": [\"ssh-ed25519 AAAA...\"]}\n  ],\n  \"update_strategy\": \"reboot\",\n  \"swap\": {\"enabled\": true, \"size_mb\": 2048}\n}\n```\n\nTo disable swap entirely:\n\n```json\n{\n  \"hostname\": \"flatcar-01\",\n  \"channel\": \"stable\",\n  \"disk\": \"\u002Fdev\u002Fdisk\u002Fby-id\u002Fata-SomeSeagate_1TB\",\n  \"network\": {\"mode\": \"dhcp\"},\n  \"users\": [\n    {\"username\": \"core\", \"ssh_keys\": [\"ssh-ed25519 AAAA...\"]}\n  ],\n  \"update_strategy\": \"reboot\",\n  \"swap\": {\"enabled\": false}\n}\n```\n\nFor the full field reference see [docs\u002FHEADLESS-CONFIG.md](docs\u002FHEADLESS-CONFIG.md).\n\nValid `swap.size_mb` range: 1–32768 (MiB). Omitting `swap` or setting `size_mb: 0` uses the 4 GiB default.\n\n## Development\n\n```bash\njust              # list all recipes\njust ci           # full CI: tidy + fmt + vet + lint + vuln + test-race + cover + headless-e2e + build\njust build        # GOOS=linux GOARCH=amd64 CGO_ENABLED=0 → bin\u002Fknuckle\njust build-arm64  # cross-compile arm64 → bin\u002Fknuckle-arm64\njust test         # go test .\u002F...\njust vuln         # govulncheck .\u002F...\njust cover        # coverage profile + summary\njust cover-check  # per-package coverage threshold gate\njust headless-test  # build + canned JSON config (CI gate, runs on host)\n```\n\n### VM Testing\n\n```bash\njust vm           # real install in QEMU → auto-boots installed system after\njust vm-e2e       # automated: headless install → boot → verify SSH + hostname (4 passes)\njust hardware-repro # installer ISO in a hardware-like VM, captures install failure artifacts\njust boot-iso     # build ISO → boot in QEMU GTK window\njust e2e          # build ISO → boot → interactive install\njust ssh          # SSH into running VM\n```\n\n`just vm` downloads a Flatcar stable QEMU image, boots a VM with two disks (boot + target), SCPs the binary in, and launches knuckle over SSH. After install completes, it kills the installer VM and boots from the installed target disk to verify SSH works.\n\n`just vm-e2e` is fully automated — runs 4 passes (DHCP, static network, docker sysext, NVIDIA), verifying hostname, OS version, update strategy, and sysext activation on each.\n\n`just hardware-repro` boots the installer ISO with `q35`, UEFI, a SATA target disk, and an `e1000e` NIC so the VM looks more like a generic physical machine than a paravirtualized guest. It then runs the same `internal\u002Finstall` path via `--headless` and saves the useful artifacts under `.vm\u002F` (`hardware-install-output.log`, `hardware-knuckle.log`, `hardware-journal.log`, `hardware-disk-inventory.log`, `hardware-installer-serial.log`).\n\nARM64 VM testing: `KNUCKLE_ARCH=arm64 just vm` (requires native arm64 hardware or QEMU TCG). Set the same env var for other arm64-targeted `just` recipes such as `build`, `vm-e2e`, `iso`, and `boot-iso`.\n\n**Prerequisites:**\n- **Go 1.26+** and **[just](https:\u002F\u002Fjust.systems)**\n- **QEMU with KVM:**\n  - Ubuntu\u002FDebian: `apt install qemu-system-x86-64 qemu-efi-aarch64 ovmf`\n  - Fedora\u002FRHEL: `dnf install qemu-system-x86 qemu-system-aarch64 edk2-ovmf`\n  - Arch: `pacman -S qemu qemu-efi-aarch64 edk2-ovmf`\n- **OVMF firmware** — required for `just hardware-repro` (auto-installed above) and UEFI VM testing\n- **Flatcar QEMU base image** — download via [docs\u002FGHOST-LAB.md](docs\u002FGHOST-LAB.md) before first run. `just vm` will fail if the image is missing\n\n## Architecture\n\n```\ncmd\u002Fknuckle\u002F         → CLI entrypoint, flag parsing, runner wiring\ninternal\u002Fbakery\u002F     → sysext catalog + Flatcar release\u002FSBOM fetchers, SHA512+GPG verification\ninternal\u002Fgithub\u002F     → SSH key fetch + GitHub Releases API client\ninternal\u002Fheadless\u002F   → --headless --config JSON-driven install path\ninternal\u002Fignition\u002F   → Butane assembly + in-process Butane→Ignition compilation\ninternal\u002Finstall\u002F    → flatcar-install orchestration via runner\ninternal\u002Fiso\u002F        → installer ISO builder helpers\ninternal\u002Fmodel\u002F      → shared data types (InstallConfig, DiskInfo, NetworkInterface)\ninternal\u002Fprobe\u002F      → lsblk + ip addr JSON parsing, \u002Fdev\u002Fdisk\u002Fby-id resolution\ninternal\u002Frunner\u002F     → Runner interface: RealRunner, DryRunner, SpyRunner\ninternal\u002Ftui\u002F        → Bubble Tea view models (one sub-model per step)\ninternal\u002Fvalidate\u002F   → hostname, CIDR, gateway, SSH key, timezone, disk path validators\ninternal\u002Fwizard\u002F     → step state machine, navigation, validation gates\n```\n\n### Key Design Decisions\n\n- **Runner abstraction** — every external command goes through `internal\u002Frunner.Runner`. Three implementations: `RealRunner` (prod), `DryRunner` (no-op + logging), `SpyRunner` (test recorder). Reboot is injected via `rebootFn`.\n- **Flatcar Butane variant** — `variant: flatcar`, compiled in-process via `github.com\u002Fcoreos\u002Fbutane` v0.28+. No `butane` CLI needed on the target system.\n- **Architecture-aware** — `InstallConfig.Arch` is set from `runtime.GOARCH` (compile-time constant). Sysext catalog, channel fetches, and ISO builds all parameterize on arch. LTS channel is guarded for arm64 (not published by Flatcar).\n- **Sysext catalog** — from [flatcar\u002Fsysext-bakery](https:\u002F\u002Fgithub.com\u002Fflatcar\u002Fsysext-bakery) GitHub Releases API; selects `x86-64.raw` or `arm64.raw` assets based on target arch.\n- **Channel versions** — assembled from SBOM JSON (preferred), `version.txt`, package lists, and `rootfs-included-sysexts`.\n- **Supply-chain verification** — SHA512 digest check + GPG signature verification against embedded Flatcar signing key.\n- **Disk identity** — `\u002Fdev\u002Fdisk\u002Fby-id` preferred; never trusts `\u002Fdev\u002FsdX` enumeration order.\n- **Headless mode** — mirrors TUI path through the same `internal\u002Finstall` package. JSON config schema with `arch` field.\n- **ISO injection** — modifies Flatcar's `usr.squashfs` directly (the only reliable method for Flatcar PXE live boot). Uses systemd-boot (UEFI-only, BLS entries).\n\n## Tech Stack\n\n- [Go](https:\u002F\u002Fgo.dev) 1.26+ (CGO_ENABLED=0, static binary)\n- [Bubble Tea v2.0.6](https:\u002F\u002Fgithub.com\u002Fcharmbracelet\u002Fbubbletea) — TUI framework\n- [Lip Gloss v2.0.3](https:\u002F\u002Fgithub.com\u002Fcharmbracelet\u002Flipgloss) — styling\n- [Huh v2.0.3](https:\u002F\u002Fgithub.com\u002Fcharmbracelet\u002Fhuh) — form inputs (Dracula theme)\n- [Bubbles v2.1.0](https:\u002F\u002Fgithub.com\u002Fcharmbracelet\u002Fbubbles) — reusable components\n- [Butane v0.28](https:\u002F\u002Fgithub.com\u002Fcoreos\u002Fbutane) — Ignition config compilation (in-process)\n- [ProtonMail\u002Fgo-crypto](https:\u002F\u002Fgithub.com\u002FProtonMail\u002Fgo-crypto) — GPG signature verification\n- [flatcar-install](https:\u002F\u002Fwww.flatcar.org\u002Fdocs\u002Flatest\u002Finstalling\u002Fbare-metal\u002Finstalling-to-disk\u002F) — disk provisioning\n\n## CI\u002FCD\n\n- **CI** (`ci.yml`) — go mod tidy, gofmt, vet, golangci-lint, govulncheck, test -race, per-package coverage gate, headless e2e, arm64 cross-compile\n- **Security** (`security.yml`) — CodeQL (Go), OSSF Scorecard, dependency-review\n- **Release** (`release.yml`) — triggered on `v*` tags; builds amd64 on `ubuntu-latest`, arm64 on `ubuntu-24.04-arm`; produces binaries + installer ISOs + cosign bundles\n\n## After Install\n\nOnce knuckle finishes, the machine reboots into a running Flatcar system. Here's what to do next.\n\n**Log in** — SSH as the `core` user with the key(s) you provided during setup:\n\n```bash\nssh core@\u003Cip-or-hostname>\n```\n\nNo password login by default; the key you entered (or fetched from GitHub) is the only way in.\n\n**Check the system** — Flatcar is an immutable OS. The root filesystem is read-only; user state lives under `\u002Fvar`, `\u002Fetc`, and `\u002Fhome`. To see what's running:\n\n```bash\nsystemctl list-units --type=service\njournalctl -b          # boot logs\ncat \u002Fetc\u002Fos-release    # OS version\n```\n\n**System extensions (sysexts)** — if you installed Docker, Kubernetes, or other sysexts, they land in `\u002Fetc\u002Fextensions\u002F` and activate on the next boot (or immediately via `systemd-sysext refresh`). Check status:\n\n```bash\nsystemd-sysext status\ndocker version          # if docker sysext was installed\n```\n\n**Updates** — Flatcar auto-updates by default. The update strategy you chose controls how reboots happen:\n\n| Strategy | Behaviour |\n|---|---|\n| `reboot` | Reboots automatically when an update lands |\n| `etcd-lock` | Co-ordinates reboots across a cluster via locksmith |\n| `off` | Downloads updates but never reboots — you reboot manually |\n\nCheck update status: `update_engine_client -status`\n\n**Install more software** — the read-only root means traditional package managers don't apply. Options:\n- **Sysexts** — system-level tools (Docker, Kubernetes, Tailscale, NVIDIA) via the [Flatcar Bakery](https:\u002F\u002Fflatcar.github.io\u002Fsysext-bakery\u002F)\n- **Containers** — run workloads with Docker or another container runtime\n- **Toolbox \u002F distrobox** — `toolbox enter` drops you into a mutable Fedora container for ad-hoc CLI work\n\n**Reprovisioning** — to change config (add users, switch update strategy, add sysexts), edit the Ignition\u002FButane source and re-run knuckle. Flatcar is designed for reprovisioning rather than in-place mutation.\n\n## Community\n\n- [Flatcar on Discord](https:\u002F\u002Fflatcar.org\u002Fdiscord) — chat with the Flatcar community\n- [Flatcar docs](https:\u002F\u002Fwww.flatcar.org\u002Fdocs\u002F) — official documentation\n- [Troubleshooting guide](docs\u002FTROUBLESHOOTING.md) — common install\u002Ffirst-boot fixes and diagnostic commands\n- [knuckle issues](https:\u002F\u002Fgithub.com\u002Fprojectbluefin\u002Fknuckle\u002Fissues) — file bugs and ideas\n\n## License\n\nApache 2.0\n","Knuckle 是一个用于在裸机上部署 Flatcar Container Linux 的现代交互式终端用户界面工具。它通过提供类似于 Ubuntu Server 的安装体验，简化了 Ignition 文件的生成和传递过程，使得用户无需直接处理复杂的 Ignition 配置。项目采用 Go 语言编写，具备良好的代码覆盖率和质量保证。适用于希望在家庭或小型办公环境中快速搭建基于 Flatcar 的容器化基础设施，并且偏好使用直观图形界面而非命令行进行系统初始化的场景。需要注意的是，当前版本仍处于非常早期的预发布阶段，存在一定的不稳定性和限制条件，如仅支持 UEFI 引导模式等。",2,"2026-06-11 04:07:31","CREATED_QUERY"]