Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export default defineConfig({
sitemap: {
hostname: 'https://lok8s.io/',
},
// Internal/planning docs now live in the PRIVATE kubehz-cluster repo
// (docs/internal/). lok8s is public — keep only this defensive exclude so a
// stray internal/** file can never ship to the public site by accident.
// Defensive net: nothing under docs/internal/ is part of this site.
// Keep this exclude so a stray internal/** file can never ship to the
// public site by accident.
srcExclude: ['internal/**'],
head: [
['meta', { name: 'theme-color', content: '#89DCEB' }],
Expand Down Expand Up @@ -48,6 +48,7 @@ export default defineConfig({
items: [
{ text: 'Getting Started', link: '/guide/' },
{ text: 'Concepts', link: '/guide/concepts' },
{ text: 'The Toolchain (b.yaml)', link: '/guide/toolchain' },
{ text: 'Addons', link: '/guide/addons' },
],
},
Expand Down
3 changes: 2 additions & 1 deletion docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ and the rest of your profile's toolchain — ships **pinned inside the lok8s
environment** and lands in your project's `.bin/` with a single command
(`b install`; see [Installation](#installation) below). Nothing touches
your system, versions are locked per project, and teammates get the
identical toolchain from the committed `b.yaml`/`b.lock`.
identical toolchain from the committed `b.yaml`/`b.lock` — see
[The Toolchain](/guide/toolchain) for the file's schema.

## Installation

Expand Down
11 changes: 11 additions & 0 deletions docs/guide/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ This guide covers:
where their source is. `lok8s.yaml` is the **how**: Dockerfile path,
live-update sync rules, port forwards, Tilt resource config.

::: warning Service names and target names are different namespaces
A **service name** is a key under `services:` in `services.yaml`. It names
the image (`lok8s.local/<service>`) and claims manifests through the
`lok8s.dev/name=<service>` label — Tilt resources and this page use it.
A **target name** is a directory under `clusters/<domain>/targets/` — the
[domain kustomization](/guide/concepts#plane-b-—-workloads-targets) and
`lo build` use it. The two can share a string, but nothing connects them
except the labels you put on the target's manifests. `lo deploy -l
lok8s.dev/name=<x>` selects by **label value**, not by target directory.
Comment on lines +38 to +39
:::

`services.<config>.yaml` files are **workflow profiles** — see the
[Workflow profiles](#workflow-profiles) section for the full pattern.

Expand Down
154 changes: 154 additions & 0 deletions docs/guide/toolchain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# The Toolchain (`.bin/b.yaml`)

Every lok8s project carries a pinned toolchain in `.bin/`. The file that
declares it is `.bin/b.yaml`, managed by [`b`](https://github.com/fentas/b)
— a binary manager and env-file syncer ([binary.help](https://binary.help)).
lok8s itself is distributed as a `b` environment: `b` installs the `lo` CLI,
the `.lok8s/` framework tree, and every tool the framework calls.

This page documents what `b` does in a lok8s project and the `b.yaml`
fields lok8s actually uses. For the full `b` feature set, see the
[upstream docs](https://binary.help).

::: info Documented against `b` v4.18.x
`b` ignores keys it does not know, so a field name from a different
version fails silently: the binary still installs, just with default
behavior. If something here does not match what you see, check
[binary.help](https://binary.help) for your version.
:::

## How `b` fits the `lo` workflow

`b` owns two things in a lok8s project:

1. **Binaries** — kubectl, kustomize, sops, tilt, kind, and the rest land
in `.bin/`, pinned per project. Nothing touches your system.
2. **Framework files** — `.lok8s/**`, the Tilt extension, the kustomize
plugins, and `.bin/b.yaml` itself sync from the upstream lok8s repo.

The commands you run:

```bash
# Join an existing lok8s project: install the exact pinned toolchain
b install

# Start a new project: add a lok8s profile, then install
b env add github.com/kernpilot/lok8s#local
b install

# Pull framework updates + binary upgrades
b update

# CI: exit non-zero when anything is out of date
b version --check

# Verify installed artifacts against b.lock checksums
b verify
```

`b install` reads `.bin/b.yaml` and writes `b.lock` (versions + SHA256),
so teammates and CI get the identical toolchain. The
`curl -fsSL https://get.lok8s.io | sh` bootstrap from
[Getting Started](/guide/#installation) runs these same commands for you.
Comment on lines +50 to +52

`b` picks the install directory from the first of these that is set:
`PATH_BIN`, then `PATH_BASE`, then `<git-root>/.bin`, then `<cwd>/.bin`.
Note that `PATH_BIN` and `PATH_BASE` are used **verbatim** — `b` does not
append `.bin` to them, it only does that for the git-root and working-
directory fallbacks. The `.envrc` that ships with every profile exports
these for [direnv](https://direnv.net/) users.

::: tip Authentication
Public sources need no token. Set `GITHUB_TOKEN` only for private repos
or to raise GitHub API rate limits.
:::

## The `binaries` section

`binaries` is a map. Each key is either a **pre-packaged name** (`kubectl`,
`jq`, `sops`, …— `b search <name>` lists them) or a **provider ref**
(`github.com/arg-sh/argsh`, `oci://docker`, `go://…`, `git://…`). An empty
value `{}` means "latest, defaults".

Fields lok8s uses, from the real `.bin/b.yaml`:

```yaml
binaries:
oci://docker: {} # docker CLI from an OCI image, daemonless

renvsubst:
alias: envsubst # install under a different name
groups: [core] # profile tag (see below)

github.com/arg-sh/argsh:
asset: argsh # pick this release asset by glob
groups: [core]
onPost: "${B_BIN} builtin ${B_EVENT}" # hook after install/update

github.com/mgoltzsche/khelm:
file: ../.kustomize/khelm.mgoltzsche.github.com/v2/chartrenderer/ChartRenderer
groups: [kustomize] # custom install path (relative to b.yaml)
```

| Field | Purpose |
|---|---|
| `version` | Pin a version (tag). Without it, `b` installs the latest and `b update` upgrades. |
| `alias` | Install the binary under a different name on `PATH`. |
| `asset` | Glob that selects one release asset when a release ships several. |
| `file` | Custom install path, relative to the `b.yaml` location. lok8s uses this to place kustomize exec plugins under `.kustomize/`. |
| `onPost` | Shell hook that runs after a successful install or update, only when the binary on disk changed. Gets `B_EVENT` (`install`\|`update`), `B_NAME`, `B_VERSION`, `B_FILE`. |
| `groups` | **Not a `b` field.** A lok8s convention: `b` preserves unknown keys, and the profile `select` expressions below filter on this tag. |

## The `profiles` section

`profiles` is `b`'s env-sync feature: an upstream repo publishes named
file sets, and consumers subscribe with
`b env add github.com/kernpilot/lok8s#<profile>`. lok8s publishes five:

| Profile | Includes | Adds |
|---|---|---|
| `core` | — | `.lok8s/**`, `.envrc`, `.gitignore`, `.mcp.json`, skills, and the `core`-tagged binaries |
| `kustomize` | — | `.kustomize/**` plugins and their binaries |
| `local` | core + kustomize | `Tiltfile`, `services.yaml`, kind/Tilt/mkcert/bats |
| `capi` | local | `clusterctl`, `hcloud` |
| `kubeone` | local | `kubeone`, `hcloud` |

Each profile entry has a `description`, optional `includes` (compose from
other profiles), and a `files` map of glob patterns to sync. One pattern
deserves a note — the profile syncs a **filtered** `b.yaml`:

```yaml
profiles:
core:
files:
.lok8s/**:
.bin/b.yaml:
select:
- "{binaries: from_items(items(binaries)[?[1].groups && contains([1].groups, 'core')])}"
```

`select` extracts keys from a YAML file instead of syncing it whole; a
[JMESPath](https://jmespath.org/) expression here keeps only the binaries
tagged with the profile's group. The effect: a `core` consumer's
`.bin/b.yaml` lists only the `core` binaries — each profile ships the
tools it needs and nothing else.

You rarely touch `profiles` as a consumer. `b env add` copies the resolved
profile into your local `b.yaml`, and `b update` keeps it in sync.

## Adding your own tools

Your project's `.bin/b.yaml` is yours after sync. To add a tool:

```bash
b install --add github.com/derailed/k9s # install + record in b.yaml
b install --fix jq@1.7 # install + pin the version
```

Or edit `.bin/b.yaml` directly and run `b install`. Commit `b.yaml` and
`b.lock` so the whole team gets the same tool.

## See also

- [Getting Started](/guide/) — profiles and the bootstrap path
- [`b` on GitHub](https://github.com/fentas/b) · [binary.help](https://binary.help) — the full manual: providers, env-sync strategies, Docker usage
Loading