---
title: "Ring CLI"
description: "The ring command ships in the public repo at cli/. Use upgrade to pull upstream system updates into your clone, config and test for local checks, and prod or status only when you run your own Kubernetes cluster."
locale: "en"
---
# Ring CLI

> **Info**
> **Status:** the Ring CLI ships in the public repository at `cli/`. Earlier docs said it was enterprise-only, and that is no longer true. `upgrade`, `config` and `test` work for any clone. `prod` and `status` expect a Kubernetes cluster you reach over SSH and manifests you supply. Use the **Founder** / **Developer** tabs in the sidebar to filter this page.

The `ring` command is a small Node.js tool (`commander`, Node 18 or newer) that lives next to the app in the Layer 1 repo: `ring/cli/` beside `ring/web/`. It handles three jobs: pulling upstream Ring updates into your clone, keeping a local deploy config, and rolling a Docker image onto Kubernetes.

| Earlier docs said | Current repo |
|-------------------|--------------|
| CLI is not in the public GitHub repo | `cli/` is tracked at the repo root and published |
| Use `npm link` then `ring --version` | Run `npm run cli:install` from `web/`, then `ring --help` |
| `ring deploy prod` | The command is `ring prod`. There is no `deploy` subcommand |
| Community uses scripts only | Community can use `ring upgrade` for safe upstream merges |

### For founders

## What the CLI does for your clone

  
- **[Stay current](/docs/development/community-tooling.md)** — `ring upgrade` previews which Ring system files changed upstream and merges them only when you say so.

  
- **[Self-host](/docs/deployment/self-hosted.md)** — No cluster? Use `install.sh` and a plain Node or Docker host. The CLI is optional.

  
- **[Managed hosting](/docs/development/oss-vs-enterprise.md)** — Ringdom settlers get the build and deploy pipeline run for them.

### Typical scenarios

1. **You forked Ring months ago.** Your developer runs `ring upgrade` to see what changed upstream, reviews the diff, then applies it. Nothing is committed automatically.
2. **You run your own Kubernetes.** Your developer points the CLI at your control node, registry and namespace, then ships new versions with `ring prod`.
3. **You only need a single server.** Skip the CLI. Follow the self-hosted guide.

> **Tip**
> Out of the box, the CLI defaults point at Ringdom's own production cluster and registry. Ask your developer to set your own values with `ring config` before running `prod` or `status`.

### For developers

## Install

**Link the binary**

{`npm run cli:install   # cd ../cli && npm install && npm link
ring --help

# or run without a global link
npm run cli:dev -- --help`}

**Point it at your infrastructure**

Config is stored in `~/.ring-platform.org/config.json` and starts from defaults in `cli/config.js`.

{`ring config --set k8s.controlNode=
ring config --set k8s.namespace=
ring config --set k8s.deployment=
ring config --set app.url=https://
ring config --list`}

## Commands (from `cli/index.js`)

| Command | What it does | Main options |
|---------|--------------|--------------|
| `ring upgrade` | Three-way merge of upstream system files into your clone. Preview by default | `--apply`, `--repo `, `--branch `, `--force` |
| `ring config` | Read and write `~/.ring-platform.org/config.json` | `--set k=v`, `--get k`, `--list`, `--reset` |
| `ring test` | Database and service checks | `--type db-connection\|db-service\|user-data\|username` |
| `ring prod` | Docker build, push, `kubectl apply`, `set image`, rollout wait | `--deploy-version`, `--skip-build`, `--skip-push`, `--skip-deploy`, `--skip-manifest-apply`, `--apply-k8s-secrets`, `--dry-run` |
| `ring status` | Pods, services and ingress over SSH, then `GET {app.url}/api/health` | none |

`ring prod` also has `--forge-buildkit` and `--from-forge`. Both drive Ringdom's private builder and are not useful outside it.

## How `ring upgrade` works

- **Upstream:** `upgrade.repoUrl` defaults to `https://github.com/connectplatform/ring`, branch `main`, remote name `ring-upstream`.
- **Base:** the last synced upstream commit (`upgrade.lastSyncedRef`). Only files changed between base and upstream are touched.
- **Excludes:** paths in `.reggie-propagate-exclude.json` are always skipped.
- **Safety:** conflicts are left as standard git markers. Nothing is committed. History goes to `.ring-upgrade-history.json` at the git root.

{`ring upgrade            # dry run: list upstream changes
ring upgrade --apply    # write the merge to your working tree
git diff                # review, then commit yourself`}

## What `ring prod` needs

| Input | Where it comes from |
|-------|---------------------|
| Image repository | `RING_DOCKER_REGISTRY` / `RING_DOCKER_NAMESPACE` / `RING_DOCKER_IMAGE` (defaults: Ringdom registry) |
| Manifests | `web/k8s/deployment.yaml`, else `k8s/` in the org overlay (`cli/paths.js` `resolveK8sDir`). Not in the public repo |
| Cluster secrets | `--apply-k8s-secrets` reads `RING_K8S_SECRETS_YAML` or `k8s/secrets.yaml` |
| Build args | `RING_CLI_SECRETS_PATH` JSON (`build_args`) |
| kubectl host | `k8s.controlNode`, or `RING_K8S_SSH_HOST` for one run |

Always run `ring prod --dry-run` first. It prints every build, push and `kubectl` command without running them.

## Known gaps

## Related documentation

  
- [development/community-tooling](/docs/development/community-tooling.md) — Next-step: the full list of public setup scripts that sit beside the CLI.

  
- [development/oss-vs-enterprise](/docs/development/oss-vs-enterprise.md) — See-also: which parts of the CLI pipeline only run inside Ringdom.

  
- [deployment/self-hosted](/docs/deployment/self-hosted.md) — Same-workflow: deploying without Kubernetes, where the CLI is optional.
