Introducing mirrord up: Shared-Cluster Development in One Command
mirrord runs a service on your laptop but wires it into a real Kubernetes cluster. Its outbound calls hit the deployed services, its environment variables come from the real pod, its queue reads come from the real broker.
Until now, the way you did that was mirrord exec, launched with a mirrord.json config file. That config exposes every knob mirrord has: HTTP filters, queue splitting, network modes, targets, and so on. For a given task you had to know which combination of fields matched what you were trying to do. “I want only my traffic reaching my local copy of a service, without disturbing my teammates on the same shared cluster”, for example, turned into an HTTP filter for incoming requests, a queue-splitting rule that lined up with it, and both agreeing on how to identify your session.
mirrord exec also needed to be run per service. So if you had a change that spanned three services it would mean three terminal tabs, three different mirrord exec commands, and three mirrord.jsons to manage.
mirrord up addresses both. Instead of composing mechanisms in mirrord.json, you name the use case, and mirrord picks the mechanisms. And instead of one mirrord exec per service, one mirrord-up.yaml describes them all, and one command runs them.
Naming the use case
Take the “only my traffic reaches my local copy” example. With mirrord up, it becomes:
mirrord up --mode split
--mode split is a use case, not a mechanism. Behind it, mirrord tags your session with a key (defaulting to your OS username, overridable with --key), threads that key through both the HTTP filter and the queue routing as baggage, and delivers matching traffic to your local process. Everything the two config sections in mirrord.json would have done, expressed as one flag.
The config keeps shrinking
Once you’re describing use cases instead of composing mechanisms, most of the fields you used to fill in stop being necessary. split is the default, so if that’s the case you’re in, you don’t need to name it. Routing follows from your session key. Filters and network modes fall out of the use case. Even the pod to target can be picked for you the first time you run mirrord up.
A real minimal file looks like this:
services:
order-service:
run:
command: ["npm", "run", "dev"]
You tell mirrord what to run. It fills in the rest.
This also fixed something small that tripped people up more than it should have. With mirrord exec, you still had to know the launch command: mirrord exec -f mirrord.json -- npm run dev. In mirrord up, the run command lives in the file, so whoever authors it encodes how the service starts, and everyone else just types mirrord up.
Running several services at once
mirrord-up.yaml accepts a map of services, and mirrord up runs a session for each of them in parallel, in the foreground. Hit ctrl+c and they all shut down together. It’s the same idea as docker compose, but for mirrord sessions instead of containers.
Because mirrord-up.yaml lives in the repo, a new engineer can clone it and get the same setup as everyone else, without a per-person launch script.
Getting started
The fastest path to a working file is the interactive wizard:
mirrord up init
It walks you through your common settings and one or more services, then writes a mirrord-up.yaml containing only the values you actually set. From the same directory:
mirrord up
and every service in the file starts in parallel against your cluster.
mirrord exec is not going anywhere. When you need a specific mechanism at a specific altitude, the full configuration is still there. But for the case most teams actually spend their day in, running one or a few services locally against a shared cluster, mirrord up is meant to be the boring, reproducible, one-command answer.
If you’re on mirrord exec today, try mirrord up and let us know how it goes. If you find you can’t switch, or you’d rather stay on exec, that is exactly the feedback we want. Join our community Slack and tell us why.
