Skip to content
In this Guide

In this Guide

Deep Dives

AI: Claude and Codex patterns

ConfigHub: Deploy and manage

A Guide

Deploy one thing, and look before you do

Pick one Catalog entry and read the exact Kubernetes objects it installs. Then save it in ConfigHub, release it to a cluster, and compare your result with one dated run.

Who this is for. You want to deploy one app or package, and you want to see what it installs before anything runs.

What you get. You get the exact objects for one Catalog entry, the commands that saved and released it, and the end state that one dated run reached.

What each part needs. Looking needs curl, shasum, kustomize and cub with the installer plugin, and it needs no account and no cluster. Comparing two bases also needs the workshop plugin. Saving needs a ConfigHub account. Releasing and promoting need that account, Docker, kind and kubectl. One command then creates a local kind cluster and installs Argo CD on it.

Where you can stop. Stop after the look, and nothing is saved anywhere. Stop after the save, and the entry is in ConfigHub with nothing on a cluster.

1. Choose what to deploy

Start from what you have. Each row leads to a page that is on this site today.

You start fromGo toWhat you find there
A Helm chartConfigsSearch for the chart and its version. The chart page lists the tested starting configurations and carries the five steps this page follows.
An AICR recipeConfigs, then Try NVIDIA AICR for GPUsConfigs lists the AICR entries too, and each entry page carries the same five steps. The second page pulls one retained configuration to read, with no GPU.
A stackStacksEvery shipped stack is listed with the check that looks for conflicts between its parts before anything renders.
An example appApps, then Put an app on a platformApps lists every worked example app. The Guide checks one app against the platform it would run on.
Your own YAML or OCIIs my configuration right?, then OCI shapesThe first page checks your own chart and values, or YAML you have already rendered. The second names each OCI shape and the tool that reads it.

The steps on this page come from the five steps that chart pages and AICR entry pages carry. Stacks and apps have their own checks, so this page does not describe one path for every kind.

Each entry page says what the Catalog has run for that entry. A step with a missing precondition gives no command there.

This page follows one entry, bitnami-nginx-24-0-2-http-clusterip, because a dated walk delivered it. It is the http-clusterip base of bitnami/nginx 24.0.2, and its entry page holds the full steps.

2. Look first at what it installs and what it needs

These commands need no account and no cluster. Install cub and the installer plugin first, and that section also checks for kustomize.

Here is what the command does. cub installer is an open-source plugin for the cub CLI. cub installer setup pulls a catalog package and writes its Kubernetes files locally, leaving delivery to kubectl, Argo CD or Flux. The generated scripts stop before doing any work when the plugin or kustomize is missing.

# fetch the exact objects the Catalog keeps for this entry
$ curl -fsSL -o bitnami-nginx-24-0-2-http-clusterip.yaml https://raw.githubusercontent.com/confighub/helm-expt/main/recipes/bitnami/nginx/24.0.2/revisions/http-clusterip/r001/rendered/release-objects.yaml

# check the bytes against the listing
$ shasum -a 256 bitnami-nginx-24-0-2-http-clusterip.yaml
7fb28597f2eea8113612fa9e67ac84760cba1e72c42a4c59e4c25d284e0a94ba  bitnami-nginx-24-0-2-http-clusterip.yaml

# render the same base from the signed package, into a directory you can upload later
$ cub installer setup --pull oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/bitnami-nginx:24.0.2@sha256:7cf08c0348a32d577ffa0e16069ec6c2510ce773b372008d25b938f9546c5f67 --base http-clusterip --work-dir ./bitnami-nginx-24-0-2-http-clusterip --non-interactive --namespace nginx

The line under shasum is the value the listing expects. In the walk of 2026-10-08 the digest matched.

The file holds 5 objects. They are a Deployment, a NetworkPolicy, a PodDisruptionBudget, a Service and a ServiceAccount. In the walk the installer rendered 6 manifests, because it adds a Namespace.

The entry page records nothing that must exist before you apply this base. It lists 0 target prerequisites and 0 hook or setup routes.

The listing marks install-time inputs as not yet declared. The Catalog has therefore not ruled out a need on your own cluster.

Compare it with the other base

This version has one other base in the Catalog, existing-tls-ingress. The comparison uses cub config diff, which the workshop plugin adds, and the entry page gives the install line.

# fetch the other base of the same version
$ curl -fsSL -o bitnami-nginx-24-0-2-existing-tls-ingress.yaml https://raw.githubusercontent.com/confighub/helm-expt/main/recipes/bitnami/nginx/24.0.2/revisions/existing-tls-ingress/r001/rendered/release-objects.yaml

# list what differs between the two bases
$ cub config diff bitnami-nginx-24-0-2-http-clusterip.yaml bitnami-nginx-24-0-2-existing-tls-ingress.yaml --summary
Configuration diff: 1 added, 0 removed, 1 changed, 4 unchanged

The line under the second command is what the walk of 2026-10-08 printed. The entry page also compares this version with a later one.

3. Save it and release it

Every command in this section needs a ConfigHub account, because each one reads or writes your organization.

Save it in ConfigHub, with an account

A Space groups related Units, such as one base or one environment. A Unit is one versioned piece of configuration, and the upload makes one for each rendered object.

# sign in to your ConfigHub organization
$ cub auth login

# upload the rendered directory as a Space of Units, under names you choose
$ cub installer upload --work-dir ./bitnami-nginx-24-0-2-http-clusterip --space <your-space> --component <your-component>

# list the Units the upload created
$ cub unit list --space <your-space>

Replace each value in angle brackets with a name of your own. The entry id may already exist as a Space in your organization, and the package name as a Component.

In the walk the upload created one Space with 7 Units. Six are the rendered objects, and the seventh is installer-record, which the upload adds.

You can stop here. The entry is saved in ConfigHub and nothing is on a cluster.

Create a local cluster, with Docker and kind

A Target defines where ConfigHub delivers the Units in a Space. This command creates a kind cluster, installs Argo CD on it, and creates the Target workshop/target.

# create the cluster, its Argo CD and its Target
$ cub cluster up --name workshop --no-argobot

The walk ran this command with a cluster name of its own and with --no-argobot. Without that flag the command also installs argobot, and the walk did not observe that path.

The command changes your machine and your organization. It creates two Spaces, a Worker, a Target and a Trigger, opens ports 30010 to 30019 on the machine, and installs Argo CD from an unpinned upstream manifest.

It also prints the Argo CD admin password to the terminal.

Release it to that cluster

A Release is the published set of a Space's Units, and the cluster's Argo CD pulls it. The first command copies the base into a dev variant, which is a Space for one environment.

# copy the base onto the Target as a dev variant
$ cub variant create dev <your-space> --target workshop/target --space-pattern "template:<your-space>-dev"

# publish the Release that the cluster's Argo CD pulls
$ cub release publish <your-space>-dev

# delete the installer record, which Argo CD cannot read
$ cub unit delete --space <your-space>-dev installer-record

# publish again without it
$ cub release publish <your-space>-dev

The delete and the second publish work around a known defect. The cloned installer-record Unit carries the Target, and Argo CD v3.5.4 cannot read it. The walk saw this on cub v0.8.7 and server v0.8.9.

Without the delete the walk deployed nothing, and every cub command still exited 0. The walk ran the four commands in this order and did not try them without the first publish.

Promote a change to dev

Promotion carries a change in the base to the dev variant. In the walk the change was one replica to two on the Deployment Unit in the base, and its log holds that command.

# preview what the dev variant would take from the base
$ cub variant promote <your-space>-dev --dry-run -o mutations

# promote once you have read the preview
$ cub variant promote <your-space>-dev --change-desc "Pull the reviewed base forward"

# delete the installer record that the promotion adds back
$ cub unit delete --space <your-space>-dev installer-record

# publish the Release that carries the change
$ cub release publish <your-space>-dev

The promotion changes the dev Space and publishes nothing. It also adds the installer-record Unit back with the Target. The change reaches the cluster only after the delete and the publish.

4. See what success looked like

This is what the walk of 2026-10-08 printed after the second publish. Its names start with cwwalk-1008-, the prefix that session put on everything it created.

# the Argo CD Application, with its sync and its health
$ kubectl -n argocd get applications.argoproj.io
NAME                                                  SYNC STATUS   HEALTH STATUS
cwwalk-1008-bitnami-nginx-24-0-2-http-clusterip-dev   Synced        Healthy
cwwalk-1008-kind-argo-apps                            Synced        Healthy

# the workload on the cluster
$ kubectl -n nginx get deployment,service,pods,networkpolicy,pdb
deployment.apps/nginx   1/1     1            1           38s
service/nginx   ClusterIP   10.96.194.125   <none>        80/TCP,443/TCP   38s
pod/nginx-d9699d4ff-ps556   1/1     Running   0          37s
networkpolicy.networking.k8s.io/nginx   app.kubernetes.io/instance=nginx,app.kubernetes.io/name=nginx   38s
poddisruptionbudget.policy/nginx   N/A             1                 1                     38s

Read the Sync column, because Healthy alone is not a pass. Before the delete, the same command showed Unknown and Healthy, and nothing from the entry was on the cluster.

ConfigHub shows nothing when Argo CD fails to read a Release, so this command is the check. Argo CD took between 18 seconds and about 5 minutes to read a Release on that cluster.

After the promotion, the delete and one more publish, the walk ended with the Application Synced and Healthy and two of two replicas running.

This is a dated record of one run, on one disposable local kind cluster with Argo CD. The log says it is not a receipt for the entry, so no Catalog state rests on it.

5. Know what this run did not cover

  • The walk created the dev variant only. It created no staging variant and no production variant, so this page prints no command for either.
  • The walk did not run cub auth login, because the session used an existing login.
  • The walk did not try Flux or plain kubectl delivery.
  • The cluster ran without argobot, so the walk did not observe the result with argobot.
  • The Catalog's own delivery record for this entry ran other commands. The four release commands above have no recorded run, and they rest on the dated log alone.

To see whether your change survives a refresh from upstream, follow AI overwrites my fixes. For every step and every caution, open the entry page.

6. Go back

The walk removed this entry from ConfigHub with the first four commands, and it removed the cluster with the fifth. They delete what the earlier commands created, so run them only on names you chose.

# remove the Argo CD Application Unit from the cluster's apps Space
$ cub unit delete --space workshop-argo-apps <your-space>-dev

# publish the apps Space without it
$ cub release publish workshop-argo-apps

# delete the dev Space
$ cub space delete --recursive <your-space>-dev

# delete the base Space
$ cub space delete --recursive <your-space>

# delete the kind cluster and the two Spaces that came with it
$ cub cluster down --name workshop --delete-config

The apps Space takes the cluster's name, so it is workshop-argo-apps here.

Deleting the ConfigHub side did not remove the workload. Fourteen minutes later the Application and its two pods were still on the cluster, because the root Application does not prune.

The walk recorded no command that removes the workload and keeps the cluster. It also recorded no clean-up for the files the look wrote on the machine.