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: 7 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@
"version": "0.2",
"language": "en",
"words": [
"allapp",
"DiΓ‘taxis",
"GOFLAGS",
"Millis",
"apiregistration",
"apiserverapp",
"apiserver",
"apiservice",
"apisvc",
"clusterrole",
"clusterrolebinding",
"coder-k8s",
"codercontrolplane",
"codercontrolplanes",
"coderd",
"codersdk",
"codertemplate",
"codertemplates",
"coderworkspace",
Expand All @@ -28,15 +31,19 @@
"workspaceproxy",
"workspaceproxies",
"derp",
"crds",
"devshell",
"healthz",
"gofumpt",
"javascripts",
"kubeconfig",
"kubebuilder",
"corev",
"metav",
"mcpapp",
"mkdocs",
"pymdownx",
"readyz",
"superfences"
],
"ignorePaths": [
Expand Down
157 changes: 80 additions & 77 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,133 +1,136 @@
# coder-k8s

[![CI](https://github.com/coder/coder-k8s/actions/workflows/ci.yaml/badge.svg)](https://github.com/coder/coder-k8s/actions/workflows/ci.yaml)
[![Go](https://img.shields.io/badge/go-1.25%2B-00ADD8?logo=go)](./go.mod)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](./LICENSE)

> [!WARNING]
> **Highly Experimental / Alpha Software**
> This repository is a **hackathon contribution** and remains a **highly experimental, alpha-stage** project.
> **Do not use this in production or expose it to end users.**
>
## Project description

`coder-k8s` is a Go-based Kubernetes control-plane project with two app modes:
`coder-k8s` is a Kubernetes control-plane project for managing Coder-related resources with native Kubernetes APIs.

## What this project provides

- A controller-runtime operator for `coder.com/v1alpha1` resources:
- `CoderControlPlane`
- `CoderProvisioner`
- `CoderWorkspaceProxy`
- An aggregated API server for `aggregation.coder.com/v1alpha1` resources:
- `CoderWorkspace`
- `CoderTemplate`
- An MCP HTTP server for operational tooling.
- A single binary that can run in all-in-one mode or split app modes.

- A `controller-runtime` operator for managing `CoderControlPlane` and
`CoderWorkspaceProxy` resources (`coder.com/v1alpha1`).
- An aggregated API server for `CoderWorkspace` and `CoderTemplate` resources
(`aggregation.coder.com/v1alpha1`).
## Application modes

| Mode | Description | Typical usage |
| --- | --- | --- |
| `all` (default) | Runs controller + aggregated API + MCP HTTP together | Local dev, demos, simple cluster deployment |
| `controller` | Runs only Kubernetes reconcilers | Controller-focused debugging and e2e smoke flows |
| `aggregated-apiserver` | Runs only aggregated API server | Split deployments with explicit Coder backend flags |
| `mcp-http` | Runs only MCP HTTP server | MCP-focused integrations |

## Prerequisites

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

## Quick start / Local development (OrbStack)
## Quick start (local controller run)

```bash
# Generate CRD and RBAC manifests
# Generate and apply CRDs
make manifests

# Apply CRDs to your cluster
kubectl apply -f config/crd/bases/

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

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

# Verify
# Verify resource creation
kubectl get codercontrolplanes -A
```

## Examples

- [`examples/cloudnativepg/`](examples/cloudnativepg/) - Deploy a `CoderControlPlane` with a CloudNativePG-managed PostgreSQL backend.

## KIND development cluster (for k9s demos)

Bootstrap a KIND cluster and install CRDs/RBAC (**this also switches your current kubectl context**):
## Documentation

```bash
make kind-dev-up
```
The project docs follow DiΓ‘taxis and live in `docs/`.

> Tip: override defaults when needed:
>
> - Use `CLUSTER_NAME` to run multiple clusters in parallel.
> - Use `KIND_NODE_IMAGE` to pin the node image (default: `kindest/node:v1.34.0`).
>
> ```bash
> CLUSTER_NAME=my-cluster make kind-dev-up
> KIND_NODE_IMAGE=kindest/node:v1.32.0 make kind-dev-up
> ```
- Home: [`docs/index.md`](docs/index.md)
- Tutorial: [`docs/tutorials/getting-started.md`](docs/tutorials/getting-started.md)
- How-to guides: [`docs/how-to/`](docs/how-to/)
- Architecture: [`docs/explanation/architecture.md`](docs/explanation/architecture.md)
- API reference: [`docs/reference/api/`](docs/reference/api/)

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

```bash
make kind-dev-ctx
# or: CLUSTER_NAME=my-cluster make kind-dev-ctx
make docs-serve
```

Start the controller (pick one):

- Out-of-cluster (fast iteration):

```bash
GOFLAGS=-mod=vendor go run . --app=controller
```
## Examples

- In-cluster (closer to CI):
- [`examples/cloudnativepg/`](examples/cloudnativepg/) β€” Deploy a `CoderControlPlane` with a CloudNativePG-managed PostgreSQL backend.

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

Demo:
Bootstrap a KIND cluster and install CRDs/RBAC (**this switches current kubectl context**):

```bash
make kind-dev-k9s
make kind-dev-up
```

Cleanup:
Useful helpers:

```bash
make kind-dev-status
make kind-dev-ctx
make kind-dev-load-image
make kind-dev-k9s
make kind-dev-down
```

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

## Essential commands

| Command | Description |
| --- | --- |
| `make build` | Build the project |
| `make test` | Run tests |
| `make manifests` | Generate CRD/RBAC manifests |
| `make codegen` | Run deepcopy code generation |
| `make verify-vendor` | Verify vendor consistency |
| `make lint` | Run linter (requires `golangci-lint`) |
| `make vuln` | Run vulnerability check (requires `govulncheck`) |
| `make docs-serve` | Serve the documentation site locally (requires `mkdocs`) |
| `make build` | Build all packages |
| `make test` | Run unit + integration tests |
| `make test-integration` | Run focused controller integration tests |
| `make manifests` | Generate CRD and RBAC manifests |
| `make codegen` | Run deepcopy generation |
| `make docs-reference` | Regenerate API reference docs from Go types |
| `make docs-check` | Build docs in strict mode (CI-equivalent) |
| `make verify-vendor` | Verify vendored dependency consistency |
| `make lint` | Run linter + formatting checks |
| `make vuln` | Run vulnerability scan |

## Testing strategy
## Repository layout

- **Unit tests**: `make test` runs all tests, including unit tests in `main_test.go`.
- **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).
- **E2E smoke tests**: Recommended CI smoke coverage uses a Kind-based flow that deploys the controller image and verifies pod health.
- `api/v1alpha1/` β€” CRD API types (`coder.com/v1alpha1`)
- `api/aggregation/v1alpha1/` β€” aggregated API types (`aggregation.coder.com/v1alpha1`)
- `internal/app/` β€” app mode entrypoints (`allapp`, `controllerapp`, `apiserverapp`, `mcpapp`)
- `internal/controller/` β€” controller reconcilers
- `internal/aggregated/` β€” aggregated storage + Coder client/provider logic
- `config/` β€” generated CRDs, RBAC, samples
- `deploy/` β€” deployable manifests for all-in-one, APIService, and MCP service
- `docs/` β€” user-facing documentation site content
- `hack/` β€” code generation and maintenance scripts

## Project structure
## Contributing

- `api/v1alpha1/` β€” CRD types and generated deepcopy code
- `internal/controller/` β€” Reconciliation logic
- `config/crd/bases/` β€” Generated CRD manifests
- `config/rbac/` β€” RBAC manifests (generated role + deployment bindings)
- `config/samples/` β€” Sample custom resources
- `hack/` β€” Code generation and maintenance scripts
Before opening a PR, run at least:

```bash
make verify-vendor
make test
make build
make lint
make docs-check
```

## License

Expand Down
9 changes: 5 additions & 4 deletions config/samples/coder_v1alpha1_codercontrolplane.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ metadata:
name: codercontrolplane-sample
namespace: default
spec:
image: "ghcr.io/coder/coder-k8s:main"
licenseSecretRef:
name: coder-license
key: license
image: "ghcr.io/coder/coder:latest"
# Optional Enterprise license upload:
# licenseSecretRef:
# name: coder-license
# key: license
Loading