A compose file is the most honest description most teams have of how their app runs. Kubernetes wants twelve YAML files that say the same thing in a different accent.

CloudControl (cc) reads the compose file every System32 product already carries — a Go API, a Next.js frontend, a volume for SQLite — and produces the Deployments, Services, PersistentVolumeClaims and Ingress a cluster needs. Then it applies them, and keeps a handful of day-two verbs close at hand.

Why another tool

We ship a lot of small products and each one deploys the same way. The friction was never the cluster; it was translating a known-good compose file by hand and drifting a little each time. A converter with tests removes the drift, and a CLI with a dry run removes the fear.

If the compose file runs locally, cc ship runs it on the cluster. Nothing else to write.

The commands

01

cc ship

Convert the compose file, apply the manifests, wait for rollout.

02

cc scale / cc restart / cc stop

Change replicas, roll the pods, or scale to zero without deleting state.

03

cc update

Re-render and apply only what changed — a new image tag, a new env var.

04

cc render / cc status / cc list

Print the manifests, show rollout state, list what cc manages.

What the converter does

  • Services → Deployments + Services. Ports become container and service ports; depends_on becomes ordering hints, not runtime coupling.
  • Volumes → PersistentVolumeClaims. A SQLite data volume gets a claim and a mount, so a redeploy keeps the data.
  • Environment → ConfigMaps. Plain settings are lifted out of the container spec; secrets are referenced, never inlined.
  • Labels and names follow one convention so cc list and cc status can find their own work later.

The converter is a pure function with unit tests: compose in, manifests out. That is the part we most wanted to be boring.

Dry runs everywhere

Every mutating command accepts --dry-run and prints exactly what it would apply. It is the same rendering path as the real run, so what you review is what ships.

01 / RENDERcc render

Look at the manifests the compose file produces.

02 / PREVIEWcc ship --dry-run

See the apply plan without touching the cluster.

03 / SHIPcc ship

Apply and wait for the rollout.

04 / OPERATEcc status / scale / update

Day-two in the same vocabulary.

How it is built

A single Go binary, no daemon, no CRDs. It talks to the cluster the way kubectl does and stores nothing of its own. It is not in the product catalog — it is the tool we use to put the catalog on a cluster — and it is shared as-is for teams with the same shape of problem.

Related

The control plane that every deployed product signs in through, and the first products it runs.

PlatformOne sign-in for every product