Skip to content

Commit 030ca54

Browse files
committed
🤖 docs: refresh docs accuracy and structure
Summary: - rewrote architecture, troubleshooting, and docs index pages - improved README structure and app mode coverage - updated tutorial/deploy guides for correctness and actionability - fixed control-plane sample image and made license secret optional --- _Generated with `mux` • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh` • Cost: $2.88_ <!-- mux-attribution: model=openai:gpt-5.3-codex thinking=xhigh costs=2.88 -->
1 parent 7054680 commit 030ca54

8 files changed

Lines changed: 416 additions & 207 deletions

File tree

‎README.md‎

Lines changed: 80 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,136 @@
11
# coder-k8s
22

3+
[![CI](https://github.com/coder/coder-k8s/actions/workflows/ci.yaml/badge.svg)](https://github.com/coder/coder-k8s/actions/workflows/ci.yaml)
4+
[![Go](https://img.shields.io/badge/go-1.25%2B-00ADD8?logo=go)](./go.mod)
5+
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](./LICENSE)
6+
37
> [!WARNING]
48
> **Highly Experimental / Alpha Software**
59
> This repository is a **hackathon contribution** and remains a **highly experimental, alpha-stage** project.
610
> **Do not use this in production or expose it to end users.**
7-
>
8-
## Project description
911
10-
`coder-k8s` is a Go-based Kubernetes control-plane project with two app modes:
12+
`coder-k8s` is a Kubernetes control-plane project for managing Coder-related resources with native Kubernetes APIs.
13+
14+
## What this project provides
15+
16+
- A controller-runtime operator for `coder.com/v1alpha1` resources:
17+
- `CoderControlPlane`
18+
- `CoderProvisioner`
19+
- `CoderWorkspaceProxy`
20+
- An aggregated API server for `aggregation.coder.com/v1alpha1` resources:
21+
- `CoderWorkspace`
22+
- `CoderTemplate`
23+
- An MCP HTTP server for operational tooling.
24+
- A single binary that can run in all-in-one mode or split app modes.
1125

12-
- A `controller-runtime` operator for managing `CoderControlPlane` and
13-
`CoderWorkspaceProxy` resources (`coder.com/v1alpha1`).
14-
- An aggregated API server for `CoderWorkspace` and `CoderTemplate` resources
15-
(`aggregation.coder.com/v1alpha1`).
26+
## Application modes
27+
28+
| Mode | Description | Typical usage |
29+
| --- | --- | --- |
30+
| `all` (default) | Runs controller + aggregated API + MCP HTTP together | Local dev, demos, simple cluster deployment |
31+
| `controller` | Runs only Kubernetes reconcilers | Controller-focused debugging and e2e smoke flows |
32+
| `aggregated-apiserver` | Runs only aggregated API server | Split deployments with explicit Coder backend flags |
33+
| `mcp-http` | Runs only MCP HTTP server | MCP-focused integrations |
1634

1735
## Prerequisites
1836

1937
- Go 1.25+ (`go.mod` currently declares Go 1.25.7)
20-
- A Kubernetes cluster (OrbStack is recommended for local development; any cluster works)
21-
- `kubectl` configured to point at your cluster context
38+
- A Kubernetes cluster (OrbStack, KIND, or any conformant cluster)
39+
- `kubectl` configured for your target cluster
2240

23-
## Quick start / Local development (OrbStack)
41+
## Quick start (local controller run)
2442

2543
```bash
26-
# Generate CRD and RBAC manifests
44+
# Generate and apply CRDs
2745
make manifests
28-
29-
# Apply CRDs to your cluster
3046
kubectl apply -f config/crd/bases/
3147

32-
# Run the controller locally (uses your kubeconfig context)
48+
# Run controller locally against your kubeconfig context
3349
GOFLAGS=-mod=vendor go run . --app=controller
3450

35-
# In another terminal: apply the sample CR
51+
# In another terminal, apply a sample control plane
3652
kubectl apply -f config/samples/coder_v1alpha1_codercontrolplane.yaml
3753

38-
# Verify
54+
# Verify resource creation
3955
kubectl get codercontrolplanes -A
4056
```
4157

42-
## Examples
43-
44-
- [`examples/cloudnativepg/`](examples/cloudnativepg/) - Deploy a `CoderControlPlane` with a CloudNativePG-managed PostgreSQL backend.
45-
46-
## KIND development cluster (for k9s demos)
47-
48-
Bootstrap a KIND cluster and install CRDs/RBAC (**this also switches your current kubectl context**):
58+
## Documentation
4959

50-
```bash
51-
make kind-dev-up
52-
```
60+
The project docs follow Diátaxis and live in `docs/`.
5361

54-
> Tip: override defaults when needed:
55-
>
56-
> - Use `CLUSTER_NAME` to run multiple clusters in parallel.
57-
> - Use `KIND_NODE_IMAGE` to pin the node image (default: `kindest/node:v1.34.0`).
58-
>
59-
> ```bash
60-
> CLUSTER_NAME=my-cluster make kind-dev-up
61-
> KIND_NODE_IMAGE=kindest/node:v1.32.0 make kind-dev-up
62-
> ```
62+
- Home: [`docs/index.md`](docs/index.md)
63+
- Tutorial: [`docs/tutorials/getting-started.md`](docs/tutorials/getting-started.md)
64+
- How-to guides: [`docs/how-to/`](docs/how-to/)
65+
- Architecture: [`docs/explanation/architecture.md`](docs/explanation/architecture.md)
66+
- API reference: [`docs/reference/api/`](docs/reference/api/)
6367

64-
> If the cluster already exists and you change `KIND_NODE_IMAGE`, run `make kind-dev-down` first so the new image can be applied.
65-
>
66-
If you need to switch your kubectl context later:
68+
Serve docs locally:
6769

6870
```bash
69-
make kind-dev-ctx
70-
# or: CLUSTER_NAME=my-cluster make kind-dev-ctx
71+
make docs-serve
7172
```
7273

73-
Start the controller (pick one):
74-
75-
- Out-of-cluster (fast iteration):
76-
77-
```bash
78-
GOFLAGS=-mod=vendor go run . --app=controller
79-
```
74+
## Examples
8075

81-
- In-cluster (closer to CI):
76+
- [`examples/cloudnativepg/`](examples/cloudnativepg/) — Deploy a `CoderControlPlane` with a CloudNativePG-managed PostgreSQL backend.
8277

83-
```bash
84-
make kind-dev-load-image
85-
kubectl apply -f config/e2e/deployment.yaml
86-
kubectl -n coder-system wait --for=condition=Available deploy/coder-k8s --timeout=120s
87-
```
78+
## KIND development cluster (k9s demos)
8879

89-
Demo:
80+
Bootstrap a KIND cluster and install CRDs/RBAC (**this switches current kubectl context**):
9081

9182
```bash
92-
make kind-dev-k9s
83+
make kind-dev-up
9384
```
9485

95-
Cleanup:
86+
Useful helpers:
9687

9788
```bash
89+
make kind-dev-status
90+
make kind-dev-ctx
91+
make kind-dev-load-image
92+
make kind-dev-k9s
9893
make kind-dev-down
9994
```
10095

101-
Mux users: there is an optional agent skill (`kind-dev`) under `.mux/skills/` with agent-oriented instructions for running per-workspace KIND clusters.
102-
10396
## Essential commands
10497

10598
| Command | Description |
10699
| --- | --- |
107-
| `make build` | Build the project |
108-
| `make test` | Run tests |
109-
| `make manifests` | Generate CRD/RBAC manifests |
110-
| `make codegen` | Run deepcopy code generation |
111-
| `make verify-vendor` | Verify vendor consistency |
112-
| `make lint` | Run linter (requires `golangci-lint`) |
113-
| `make vuln` | Run vulnerability check (requires `govulncheck`) |
114-
| `make docs-serve` | Serve the documentation site locally (requires `mkdocs`) |
100+
| `make build` | Build all packages |
101+
| `make test` | Run unit + integration tests |
102+
| `make test-integration` | Run focused controller integration tests |
103+
| `make manifests` | Generate CRD and RBAC manifests |
104+
| `make codegen` | Run deepcopy generation |
105+
| `make docs-reference` | Regenerate API reference docs from Go types |
115106
| `make docs-check` | Build docs in strict mode (CI-equivalent) |
107+
| `make verify-vendor` | Verify vendored dependency consistency |
108+
| `make lint` | Run linter + formatting checks |
109+
| `make vuln` | Run vulnerability scan |
116110

117-
## Testing strategy
111+
## Repository layout
118112

119-
- **Unit tests**: `make test` runs all tests, including unit tests in `main_test.go`.
120-
- **Integration tests**: Use `envtest` to exercise reconciliation against a lightweight API server (no real cluster needed). Run them via `make test` (included in the full suite) or `make test-integration` (focused on controller tests only).
121-
- **E2E smoke tests**: Recommended CI smoke coverage uses a Kind-based flow that deploys the controller image and verifies pod health.
113+
- `api/v1alpha1/` — CRD API types (`coder.com/v1alpha1`)
114+
- `api/aggregation/v1alpha1/` — aggregated API types (`aggregation.coder.com/v1alpha1`)
115+
- `internal/app/` — app mode entrypoints (`allapp`, `controllerapp`, `apiserverapp`, `mcpapp`)
116+
- `internal/controller/` — controller reconcilers
117+
- `internal/aggregated/` — aggregated storage + Coder client/provider logic
118+
- `config/` — generated CRDs, RBAC, samples
119+
- `deploy/` — deployable manifests for all-in-one, APIService, and MCP service
120+
- `docs/` — user-facing documentation site content
121+
- `hack/` — code generation and maintenance scripts
122122

123-
## Project structure
123+
## Contributing
124124

125-
- `api/v1alpha1/` — CRD types and generated deepcopy code
126-
- `internal/controller/` — Reconciliation logic
127-
- `config/crd/bases/` — Generated CRD manifests
128-
- `config/rbac/` — RBAC manifests (generated role + deployment bindings)
129-
- `config/samples/` — Sample custom resources
130-
- `hack/` — Code generation and maintenance scripts
125+
Before opening a PR, run at least:
126+
127+
```bash
128+
make verify-vendor
129+
make test
130+
make build
131+
make lint
132+
make docs-check
133+
```
131134

132135
## License
133136

‎config/samples/coder_v1alpha1_codercontrolplane.yaml‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ metadata:
44
name: codercontrolplane-sample
55
namespace: default
66
spec:
7-
image: "ghcr.io/coder/coder-k8s:main"
8-
licenseSecretRef:
9-
name: coder-license
10-
key: license
7+
image: "ghcr.io/coder/coder:latest"
8+
# Optional Enterprise license upload:
9+
# licenseSecretRef:
10+
# name: coder-license
11+
# key: license
Lines changed: 98 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,114 @@
11
# Architecture
22

3-
`coder-k8s` builds a single binary (`coder-k8s`) that can run in one of two modes:
3+
<!-- cspell:ignore allapp crds healthz readyz codersdk mcpapp apisvc -->
44

5-
- `--app=controller`
6-
- `--app=aggregated-apiserver`
5+
`coder-k8s` is a single Go binary that can run different components depending on the `--app` flag.
76

8-
The dispatch logic lives in `app_dispatch.go`. The `--app` flag is required, and the code intentionally fails fast with an `assertion failed:` error when it is missing or invalid.
7+
## Application modes
98

10-
## Controller mode
9+
| Mode | Purpose | Default |
10+
| --- | --- | --- |
11+
| `all` | Runs controller + aggregated API server + MCP HTTP server in one process | ✅ |
12+
| `controller` | Runs only the controller-runtime manager and reconcilers | |
13+
| `aggregated-apiserver` | Runs only the aggregated API server (`aggregation.coder.com/v1alpha1`) | |
14+
| `mcp-http` | Runs only the MCP HTTP server | |
1115

12-
In controller mode, the binary runs a `controller-runtime` manager and registers the `CoderControlPlane` API types:
16+
!!! note
17+
`--app` is optional. If omitted, `coder-k8s` defaults to `--app=all`.
1318

14-
- API group: `coder.com/v1alpha1`
15-
- Kind: `CoderControlPlane`
19+
## Default process model (`--app=all`)
1620

17-
Key code paths:
21+
In `all` mode, `internal/app/allapp` creates one shared controller-runtime manager and cache, then:
1822

19-
- `internal/app/controllerapp/` — scheme construction and manager startup
20-
- `internal/controller/` — reconciliation logic (`CoderControlPlaneReconciler`)
23+
1. Registers controller reconcilers.
24+
2. Starts aggregated API server as a non-leader runnable.
25+
3. Starts MCP HTTP server as a non-leader runnable.
2126

22-
## Aggregated API server mode
27+
This keeps component startup coordinated and avoids separate cache/process management for local and demo deployments.
2328

24-
In aggregated API server mode, the binary starts an aggregated API server that installs storage for:
29+
```mermaid
30+
graph TD
31+
entry["coder-k8s (--app=all)"] --> mgr["controller-runtime manager"]
32+
mgr --> ctrl["Controller reconcilers"]
33+
mgr --> agg["Aggregated API server runnable"]
34+
mgr --> mcp["MCP HTTP runnable"]
2535
26-
- API group: `aggregation.coder.com/v1alpha1`
27-
- Resources: `coderworkspaces`, `codertemplates`
36+
ctrl --> crds["coder.com/v1alpha1 CRDs"]
37+
agg --> api["aggregation.coder.com/v1alpha1"]
38+
mcp --> tools["MCP tools over /mcp"]
39+
```
2840

29-
Key code paths:
41+
## Controller subsystem
3042

31-
- `internal/app/apiserverapp/` — API server bootstrap and API group installation
32-
- `internal/aggregated/storage/` — storage implementations (currently hardcoded in-memory objects)
43+
Controller behavior lives in:
3344

34-
## Manifests and generated assets
45+
- `internal/app/controllerapp/`
46+
- `internal/controller/`
3547

36-
- `config/` — generated CRDs and RBAC (via `make manifests`)
37-
- `deploy/` — example deployment manifests for controller and aggregated API server
38-
- `vendor/` — vendored dependencies (required by the repo workflow)
48+
Key facts:
49+
50+
- Uses controller-runtime with leader election.
51+
- Exposes health probes on `:8081` (`/healthz`, `/readyz`).
52+
- Reconciles three CRDs in `coder.com/v1alpha1`:
53+
- `CoderControlPlane`
54+
- `CoderProvisioner`
55+
- `CoderWorkspaceProxy`
56+
57+
For `CoderControlPlane`, the reconciler creates/updates a Deployment + Service in the same namespace, and writes status fields such as `status.url`, `status.phase`, and operator token references.
58+
59+
## Aggregated API subsystem
60+
61+
Aggregated API server behavior lives in:
62+
63+
- `internal/app/apiserverapp/`
64+
- `internal/aggregated/storage/`
65+
- `internal/aggregated/coder/`
66+
67+
Key facts:
68+
69+
- Serves HTTPS on port `6443` by default.
70+
- Installs `aggregation.coder.com/v1alpha1` resources:
71+
- `coderworkspaces`
72+
- `codertemplates`
73+
- Storage is **codersdk-backed**, not in-memory: requests are translated to Coder API operations.
74+
75+
Client provider behavior:
76+
77+
- In `all` mode, `ControlPlaneClientProvider` discovers eligible `CoderControlPlane` resources and reads operator token secrets dynamically.
78+
- In standalone `--app=aggregated-apiserver` mode, static configuration is expected via:
79+
- `--coder-url`
80+
- `--coder-session-token`
81+
- `--coder-namespace`
82+
83+
## MCP subsystem
84+
85+
MCP behavior lives in `internal/app/mcpapp/`.
86+
87+
Key facts:
88+
89+
- HTTP listen address: `:8090`
90+
- Endpoints:
91+
- `/mcp`
92+
- `/healthz`
93+
- `/readyz`
94+
- Provides tooling for control planes, templates, workspaces, events, pod logs, and run-state updates.
95+
96+
## Kubernetes manifests
97+
98+
- `config/crd/bases/`: generated CRDs for `CoderControlPlane`, `CoderProvisioner`, `CoderWorkspaceProxy`
99+
- `config/rbac/`: ServiceAccount and RBAC bindings (`manager-role`, `coder-k8s`, auth-delegator bindings)
100+
- `deploy/deployment.yaml`: all-in-one deployment (defaults to `--app=all`)
101+
- `deploy/apiserver-service.yaml` + `deploy/apiserver-apiservice.yaml`: aggregated API exposure
102+
- `deploy/mcp-service.yaml`: MCP service on port `8090`
103+
104+
## High-level request flow (aggregated API)
105+
106+
```mermaid
107+
graph TD
108+
client["kubectl / API client"] --> kube["Kubernetes API aggregation layer"]
109+
kube --> apisvc["APIService: v1alpha1.aggregation.coder.com"]
110+
apisvc --> agg["coder-k8s aggregated API server"]
111+
agg --> provider["ClientProvider"]
112+
provider --> sdk["Coder SDK client"]
113+
sdk --> coderd["Backing coderd instance"]
114+
```

0 commit comments

Comments
 (0)