Skip to main content

Prerequisites

  • A Kubernetes cluster reachable from your team’s browsers, with schedulable linux/amd64 nodes for the control-plane workloads (1.27+; requirements).
  • Helm 3.14 or newer. The configuration-changing upgrade examples use --reset-then-reuse-values, introduced in Helm 3.14, to apply new chart defaults while preserving the release’s existing user-supplied values.
  • A Postgres instance reachable from that cluster (requirements).
  • A DNS record pointing at the cluster’s Ingress, with a TLS cert.
  • A Skyhook-issued license JWT (your account team mints one at signing).
  • A 32+ byte secret for sealing session cookies. Generate with openssl rand -base64 48.

1. Add the chart repo

2. Decide on a Postgres source

Pick one of three patterns. Examples below all use --set for clarity; production should land these in a values.yaml you check in (excluding secrets).
Easiest. Drop the DSN into a Secret you provision yourself, then point the chart at it.

3. Install

A representative invocation:
What happens:
  1. Helm renders the manifests and creates the chart-managed Secret.
  2. The radar-hub Pod starts. Its migrate initContainer runs /migrate against your Postgres and applies any pending schema migrations transactionally before the main hub container starts.
  3. Once migrations finish, the main hub and radar-hub-web containers come up. The control plane logs license-verification status on first start (look for license verified or license is expired (warn-only ...) or license verification failed).
  4. The control plane’s first-boot probe says self-hosted install detected with no orgs yet - that’s expected; the singleton org gets created on your first break-glass login.
Watch it come up:

4. First sign-in

Open https://radar.acme.example in a browser. The login page renders the break-glass form when no OIDC is configured (and a “Sign in with SSO” button when it is). Sign in with the email + password you set in step 3. The control plane:
  • Creates the singleton org (named from --set hub.orgName=..., default Default).
  • Records you as the org’s first owner.
  • Sets the sealed session cookie and redirects you to the web app.
You should now see the cluster list (empty), the deployment-shape config in the help menu (custom docs URL etc.), and NO Billing tab in Settings.

5. Connect your first cluster

The recommended path is the Radar CLI. It inspects the selected Kubernetes cluster and opens this control plane’s consent page. For a fresh install or native Helm release, it proves that your kubeconfig identity can make the required changes and then installs or updates Radar. For a supported GitOps-managed release, it generates a source-of-truth handoff instead of mutating the live cluster.
CLI enrollment requires Radar CLI 1.8.3 or newer and radar-hub chart 1.1.0 or newer using matching Hub and Web image tags. Older control-plane images do not implement the consent device flow, and mixed Hub/Web tags are unsupported.
Before you begin:
  • Install Radar CLI 1.8.3 or newer on the operator workstation. Verify the command is present with kubectl radar cloud install --help.
  • Sign in to https://radar.acme.example with an account allowed to add clusters to the singleton organization. If the organization limits cluster creation to owners, an owner must approve the consent page.
  • Give the CLI a kubeconfig identity that can read the existing Radar deployment and Helm release, create the target namespace when needed, and create or update the rendered Radar resources, including its Secret and cluster-scoped RBAC.
  • Allow the workstation to reach https://skyhook-io.github.io/helm-charts, the customer cluster to pull the Radar image, and both the workstation and customer cluster to trust the TLS certificate for https://radar.acme.example.
The examples below use kubectl radar, which works with every supported CLI installation. Homebrew also provides the shorter radar alias. Pass the intended kubeconfig context explicitly when you know it:
The CLI prints the exact target and plan before changing anything. For a fresh install or native Helm adoption, it runs a server-side Kubernetes dry run plus explicit permission checks before creating a control-plane cluster or minting a token, so a missing Kubernetes permission fails before the browser approval step. A GitOps handoff does not mutate the live cluster; readable, unambiguous ownership is its local safety gate. For a fresh install or native Helm adoption, add --dry-run to validate discovery, chart preparation, and the planned Kubernetes mutation permissions without opening the consent flow or changing either system. For GitOps, --dry-run validates discovery, verified controller ownership, and the exact chart handoff; it cannot prove write access to the source repository or permissions the reconciler will use. If you omit --context, the CLI prints the current kubeconfig context and asks you to confirm it. -y / --yes skips only that current-context confirmation; it never grants consent to adopt an existing installation. --namespace defaults to radar, and --release defaults to radar. Either flag by itself sets the fresh-install target while keeping cluster-wide discovery enabled; one unambiguous existing Radar installation still takes precedence and supplies its actual namespace and release. Pass both --namespace and --release when you deliberately want to force an exact target. Exact targeting disables broader discovery, so do not pass both flags merely to restate the defaults when you want the CLI to find an existing installation elsewhere in the cluster. The browser page names the target organization and cluster. Approve it there. For a fresh install or native Helm adoption, leave the CLI running while it provisions Radar and confirms the outbound tunnel. For GitOps, apply the printed handoff through the source of truth while the CLI waits for the reconciled agent. On success it prints the cluster name, a direct web-app link, and a context-pinned rollout command. By default, a fresh install, native Helm adoption, and GitOps handoff target the latest published stable Radar chart. This can upgrade an older Radar release and clears an explicit image tag so the selected chart’s stable Radar version runs. The plan calls this out before approval. Use --chart-version <version> to select a particular published stable chart. The selected chart must be version 1.5.4 or newer. Native Helm adoption refuses a chart downgrade; GitOps handoff does the same when the existing chart version is available from the live workload metadata.

Existing native Helm installation

When the selected cluster already has an official Radar Helm release, the CLI offers to adopt that release in place. Adoption preserves its existing values and image repository, adds the self-hosted connection settings through a fixed token Secret, and performs an atomic Helm upgrade. Interactive adoption requires a separate confirmation after the plan. Self-upgrade support is enabled by default so an owner can later initiate an upgrade from the web app. Use --no-self-upgrade if your operating model requires every upgrade to go through the terminal or GitOps. Adoption preserves the existing rbac.helm, rbac.secrets, rbac.podExec, rbac.portForward, and rbac.metrics settings by default. Pass --enable-cloud-features only when you explicitly want to turn all five capabilities on. Fresh installs already enable them.
For non-interactive automation, --adopt-existing is the separate assertion that the existing release may be changed; -y alone remains insufficient:
After a successful adoption, the CLI prints a rollback sequence that restores the previous Helm revision before removing the connection token Secret or connected control-plane cluster. Keep that sequence with your change record.

GitOps-managed installation

When an official Radar chart Deployment carries exactly one verified Argo CD or Flux ownership signal, the CLI does not run an imperative Helm upgrade that the reconciler would undo. It prints the detected owner, the selected stable chart target, and a values handoff containing the connection Secret reference and cloud.* settings. Approve the browser consent, commit the generated changes to the source of truth, and let the reconciler apply them. The CLI can remain open for up to five minutes to confirm the tunnel, or you can verify the cluster later in the web app. The GitOps handoff forces rbac.selfUpgrade=false because a live image patch would drift from Git. It leaves the other feature RBAC settings unchanged unless you pass --enable-cloud-features, which adds the five explicit capability opt-ins to the merge fragment. An ambiguous or only weakly inferred GitOps owner is not mutated automatically. Resolve the ownership ambiguity or update the source manually.

Manual Helm alternative

Use the web app’s Connect a cluster wizard when you need to integrate the values into another workflow yourself. It mints the same rhc_* cluster credential and generates the Helm values for this self-hosted endpoint:
The wizard generates this command with the real token and cluster ID. For an existing release it also offers a --reuse-values variant that preserves your settings. Alternatively, translate the generated values and Secret into your GitOps source. Do not put the raw token in Helm values checked into Git.

6. (Optional) Add OIDC

Once break-glass is verified working, layer OIDC on top:
Break-glass remains available regardless - the route stays mounted as long as auth.breakGlass.email is set. See Authentication for IdP-specific recipes.

7. (Optional) Pin to a specific release

The chart and images are one release unit. Pin the chart version and both image tags when you need to stage an exact release:
Replace CHART_VERSION with the selected radar-hub chart version and MATCHING_RELEASE_TAG with the appVersion shown by helm show chart, after confirming that tag is published for both Hub and Web. Never mix a chart with images from another release, or mix Hub and Web release tags.

Common gotchas

  • HUB_COOKIE_PASSWORD must be at least 32 bytes - the value passed to hub.cookiePassword is shorter than 32 ASCII characters. Use openssl rand -base64 48.
  • OIDC redirect URI mismatch - your IdP must have https://<hub.publicURL>/api/auth/oidc/callback registered as an exact match. No path normalization.
  • postgres: set one of postgres.dsn, postgres.existingSecret, or postgres.cnpg.cluster - the chart fails fast at templating time when zero Postgres options are set. Pick one.
  • Migrate initContainer stuck pulling - the hub Pod stays in Init: status. Check kubectl describe pod for image-pull errors against your registry mirror.
  • Control plane logs license verification failed - confirm the JWT was pasted whole (no whitespace) and the build was cut against the matching public key. See Licensing.