🤖 feat: add CloudNativePG-backed CoderControlPlane example#38
Conversation
Add a multi-resource CloudNativePG example under `examples/cloudnativepg`, including namespace, CNPG `Cluster`, and `CoderControlPlane` manifests, plus a walkthrough README for deployment and access. --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh`_ --- _Generated with `mux` • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh` • Cost: `$1.12`_ <!-- mux-attribution: model=openai:gpt-5.3-codex thinking=xhigh costs=1.12 -->
|
@codex review Please review this PR for correctness and merge readiness. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8876f70be8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Prefix the namespace manifest filename and document the ordering so `kubectl apply -f examples/cloudnativepg/` succeeds on fresh clusters. --- _Generated with [`mux`](https://github.com/coder/mux) • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh`_ --- _Generated with `mux` • Model: `openai:gpt-5.3-codex` • Thinking: `xhigh` • Cost: `$1.12`_ <!-- mux-attribution: model=openai:gpt-5.3-codex thinking=xhigh costs=1.12 -->
|
@codex review Addressed the namespace ordering issue by renaming |
|
Codex Review: Didn't find any major issues. 🚀 ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
This PR adds a runnable multi-resource example that deploys a
CoderControlPlanebacked by CloudNativePG-managed PostgreSQL.Background
The operator already supports database wiring through
spec.extraEnv, so we can provide a realistic Coder + Postgres setup without CRD or controller changes. The goal is an easier end-to-end demo manifest set and walkthrough.Implementation
examples/cloudnativepg/namespace.yamlto create a dedicatedcodernamespace.examples/cloudnativepg/cnpg-cluster.yamlwith a single-instance PVC-backed CNPG cluster (coder-db) that bootstraps database/usercoder.examples/cloudnativepg/codercontrolplane.yamlwiring:CODER_PG_CONNECTION_URLfrom CNPG Secretcoder-db-appkeyuriCODER_ACCESS_URL=http://localhost:8080for localkubectl port-forwardsmoke testingexamples/cloudnativepg/README.mdwith prerequisites, install steps (CNPG + controller), deploy steps, readiness checks, and first-user setup flow.README.mdexamples link to discover the new CloudNativePG example.Validation
make verify-vendormake testmake buildmake lint(fails in this workspace due pre-existing formatting drift undertmpfork/coder/**, unrelated to this change)Risks
Low risk. This change is documentation/manifests only and does not modify controller runtime behavior or APIs. The main user caveat is that
CODER_ACCESS_URL=http://localhost:8080is intentionally scoped to local port-forward smoke tests.📋 Implementation Plan
Plan: Example CoderControlPlane deployment backed by CloudNativePG
Context / Why
We want a realistic, easier demo of the
coder-k8soperator that includes a managed PostgreSQL database.CloudNativePG (CNPG) is a widely used Postgres operator that:
Secretcontaining a ready-to-use connection string (uri)The
CoderControlPlaneCR already supports arbitrary env injection viaspec.extraEnv, so we can wire CNPG → Coder with no CRD changes.Evidence (what we verified)
internal/controller/codercontrolplane_controller.goDeploymentandServicenamed exactly after theCoderControlPlane(metadata.name).coder server --http-address=0.0.0.0:3000and exposes it via aServiceport (default80) → target port3000.spec.extraEnvdirectly to the Coder container.api/v1alpha1/codercontrolplane_types.go:spec.extraEnvandspec.service.{type,port,annotations}exist; no dedicated DB fields.docs/how-to/deploy-controller.md: canonical install steps for CRDs + RBAC + controller deployment (in namespacecoder-system)../tmpfork/coder/helm/coder/README.md+values.yaml(Coder upstream):CODER_PG_CONNECTION_URL.CODER_ACCESS_URLis expected in typical setups; Helm chart may default it, but our operator does not.Clustercreates a<clusterName>-appSecret that includes keyuri(Postgres URL) and a<clusterName>-rwService./setupflow to create the first admin user.CODER_DISABLE_AUTHexists.CODER_ACCESS_URLis unset, Coder may attempt to create a temporary public tunnel (*.try.coder.app).Implementation plan
1) Add a new example directory
Create a new example folder that is multi-resource and runnable via
kubectl apply:Proposed location:
examples/cloudnativepg/Files:
examples/cloudnativepg/README.mdexamples/cloudnativepg/namespace.yamlexamples/cloudnativepg/cnpg-cluster.yamlexamples/cloudnativepg/codercontrolplane.yamlexamples/cloudnativepg/kustomization.yamlto enablekubectl apply -k.Rationale:
config/samples/is good for single-CR “shape” examples, but this demo needs multiple components (namespace + CNPG cluster + CoderControlPlane).2) CNPG: define a PVC-backed Postgres cluster
Add
cnpg-cluster.yamlusing CNPG’sClusterCRD.Minimal single-instance dev/demo setup:
Notes to include in README:
coder-db-app(containsuri,username,password,database, ...)coder-db-rw(primary read-write endpoint)spec.instancesto3.3) coder-k8s: wire the CNPG Secret into
CoderControlPlaneAdd
codercontrolplane.yamlthat references the CNPG-generated Secret.Why
CODER_ACCESS_URL=http://localhost:8080is trickykubectl -n coder port-forward svc/coder 8080:80localhost:8080becauselocalhostresolves to themselves.${CODER_ACCESS_URL}/healthzfrom inside the pod; withlocalhost+ port-forward, that check cannot succeed in-cluster.So this example should explicitly frame
localhostas a UI smoke test.If we want an end-to-end workspace demo, the README should describe the alternative:
CODER_ACCESS_URLto that externally reachable address, orCODER_ACCESS_URLunset and rely on Coder’s tunnel feature (requires outbound internet).4) README: end-to-end walkthrough
The README should include:
Prereqs
kubectlhelm(for CNPG install)Install CloudNativePG operator
Install the coder-k8s controller
docs/how-to/deploy-controller.md(summarized):CoderControlPlane.Deploy the example
kubectl apply -f examples/cloudnativepg/(orkubectl apply -k ...if we add kustomize)kubectl -n coder wait --for=condition=Ready cluster/coder-db --timeout=...kubectl -n coder get secret coder-db-appPort-forward to test the UI
kubectl -n coder port-forward svc/coder 8080:80http://localhost:8080/setupto create the first admin user.Callouts / limitations
CODER_ACCESS_URL.5) (Optional) Provide two kustomize overlays
If we want a smoother UX without editing YAML, add overlays:
examples/cloudnativepg/overlays/port-forward/→CODER_ACCESS_URL=http://localhost:8080examples/cloudnativepg/overlays/ingress-or-lb/→ placeholderCODER_ACCESS_URL=https://coder.example.comandservice.type: LoadBalancer(or Ingress notes)This is optional; we can start with a single manifest + README instructions and add overlays later if desired.
Acceptance criteria / validation
When implemented, we should be able to:
Readyand createscoder-db-appwith keyuri.CoderControlPlanebecomes Ready (deployment has ready replicas)./setuppage.Non-goals
localhostas the access URL (requires a real external URL).Generated with
mux• Model:openai:gpt-5.3-codex• Thinking:xhighGenerated with
mux• Model:openai:gpt-5.3-codex• Thinking:xhigh• Cost:$1.12