Set up a Local Docker host
Run sandboxes on a Docker engine you control. Register a Local Docker host, run the operator on Docker Desktop, make it your default, and turn on persistent workspaces so an agent picks up where the last run left off instead of starting clean every time.
A Local Docker host runs sandboxes on a Docker engine you control, usually Docker Desktop on your own machine, instead of on the platform's managed compute. It is the lightest way to keep agent runs on your own hardware, the natural fit for local development, and the one host that can hold a workspace on disk between runs. This page is the how-to: register the host, run the operator, make it your own, and turn on the persistence that makes it worth doing.
For the deployment choice this sits inside, when managed, Kubernetes, or Local Docker is the right answer, read sandbox hosts and deployment options. This page assumes you have decided on Local Docker.
Before you start
Three things need to be in place:
- A Docker engine you control. Docker Desktop is the usual one, on macOS, Windows, or Linux. The operator runs as a container on that engine and launches sandboxes as sibling containers, so it needs to reach the Docker socket.
- Permission to manage hosts. Registering a host rides on the
hosts.managescope, and bringing your own host is gated by an entitlement on your workspace's plan. If you cannot see the Register host button, that is what to check with an admin. - Your workspace set up for bring-your-own hosts. Running an operator depends on the platform's messaging channel being configured for your workspace. When it is not, the operator bundle download is held back rather than handing you a bundle that cannot connect, so if the download is unavailable, this is the piece an admin enables first.
Register the host
Go to Platform → Sandbox Hosts and choose Register host. Pick the Local Docker operator kind, give it a name you will recognize later, your own laptop, a shared build box, and set the runtime families it should serve, the language runtimes your profiles need. The name you choose becomes the host's identifier, so pick it deliberately; it is fixed once you save. Save it.
The host appears in the list straight away as Awaiting operator. That is expected: you have created the record, but nothing is running against it yet. The next step is to bring up the operator that claims it.
Run the operator
A host record on its own does nothing; the operator is what actually launches containers. From the host's detail page, or its row menu, choose Download operator bundle. For a Local Docker host the bundle is a small Docker Compose project: the operator image, the mount it needs to reach your Docker socket, and a one-time key that lets it claim this host. Drop the file on the machine and bring it up the way you would any Compose project, a pull to fetch the operator image and then up to start it. The host page lists the exact commands right next to the download, so you copy rather than compose them by hand.
Once it is running, the operator dials out to the platform, claims the host, and begins checking in. Watch the host's status move from Awaiting operator to Registered, with a "last seen" that ticks over as it checks in. That is the whole handshake: you never opened a port or exposed the machine, the operator reached out and connected itself.
The key is single-use
One thing worth knowing up front: the key in the bundle is single-use by design. Each time you download the bundle, the platform issues a fresh key and retires the previous one, so an old bundle stops working the moment you generate a new one. If you re-download, bring the operator up again with the new bundle, otherwise the running operator is holding a key that no longer counts and will drop off within the hour, when the short-lived token it last exchanged expires. Download once, run it, and you will not think about this again; it only matters on the day you regenerate.
Make it your default
A profile can target "my Local Docker host" rather than one host by name, which is what lets a whole team share a single profile while each person's runs land on their own machine. To be the host that resolves to, open your host's detail page and choose Set as my Local Docker host.
From then on, any profile that targets the default Local Docker host launches its sandboxes on your operator when you are the one launching. Your teammate, with their own host set as theirs, gets their machine from the same profile. It is the pattern that makes Local Docker work for a team rather than only for one person: the profile is shared, the host is personal. You can set a host as yours before its operator is even running, so the preference is ready when you bring the operator up, and the Clear link unsets it whenever you want a portable profile to stop resolving to this machine.
Turn on persistent workspaces
This is the reason most people run Local Docker. A managed sandbox is disposable by design, which is exactly right for a clean run, but a fast local inner loop wants the opposite: the same checkout, the same installed dependencies, the same build cache, run after run. A Local Docker host can keep the workspace in a named Docker volume that survives a sandbox being torn down, so the next sandbox mounts the same working directory instead of rebuilding it from scratch.
There are two sides to turning this on: the Local Docker host is what permits a workspace to persist, and a sandbox profile is where you enable it, on the profile's Maintenance tab. A profile with persistence turned on, launched on your Docker host, is what gives you the carry-over. The host's detail page then lists the persistent workspaces it is holding, each one its own volume, whether a sandbox currently has it mounted, and when it is set to expire, with controls to inspect one or clean it out when you want a fresh start. A workspace a running sandbox is using is held until that sandbox is done, so a clean-up never pulls the floor out from under live work. The volumes live on your machine, under your control, which is the other half of why this is a Local Docker feature: persistence means state on disk, and the disk is yours.
If the operator happens to be offline when you open this section, the page does not just fail; it hands you the scoped docker volume ls, docker volume inspect, and docker volume rm commands for exactly the operator-owned volumes, so you can list, inspect, or remove a workspace directly on the machine and are never locked out of your own disk.
Supply an environment file
Some local setups need a handful of values in every sandbox, a registry endpoint, a local service URL, a feature flag. A Local Docker host can point at an environment file on the machine, and the operator passes its contents into the sandboxes it launches. You give the host an absolute path to the file (a full /Users/..., C:\..., or network path), and the operator reads it when it starts a sandbox. It validates the file at that point rather than trusting it blindly, so a missing or unreadable file surfaces as a clear problem instead of silently doing nothing, and the variable names the platform reserves for cloud identity stay off-limits.
The path is treated as host configuration, so only people who can manage the host see the path itself; everyone else just sees that an environment file is configured. And because the path is something the operator is launched with, changing it means downloading a fresh bundle and bringing the operator up again. The host page flags this for you the moment the path has changed since the running operator was set up, so you are never guessing whether a restart is needed.
Keeping it healthy
Because the operator runs on your machine, the host is healthy when the operator is running and connected, and not when it is not. The host's detail page carries a health check that names each thing the operator must be able to do, reach the Docker engine, hold permission to use it, talk to the volume API, and run the workspace-volume cleanup, so a problem points at the specific row to fix rather than a vague failure. A separate volume probe goes one step further when you want certainty: it creates and then removes a throwaway volume to prove the whole persistence path actually works, not just that the API answers. If you stop the operator, or your machine sleeps, it stops checking in and the host's last-seen goes stale; the status reflects the dropped connection, and bringing the operator back up reclaims the host on its next check-in.
Keeping the operator current is an ordinary Compose update: pull the latest image and bring the project back up. Your existing key keeps working, because it only changes when you deliberately re-download the bundle, so a routine update does not turn into a reconnection chore.
When you are done with a host for good, retiring it is a deliberate step, not a side effect. Deleting a host from the Sandbox Hosts list cleans up the operator-owned volumes and any warm capacity it held, and it tells you plainly that profiles still pointed at it will not launch until you move them, so a host never disappears out from under the work that depends on it.
Cloud identity, when you need it
If sandboxes on your Local Docker host need to authenticate to a cloud resource as a workload identity rather than carrying a long-lived secret, the platform can issue the short-lived tokens for that, the same Azure Workload Identity model the Kubernetes host uses, adapted for the local case with a platform-run OIDC issuer. Turning it on has two preconditions:
- The identity issuer has to be enabled for your workspace. The host will not let you check the Azure Workload Identity box until it is.
- Each profile that wants it supplies its own Azure tenant and client id and a matching federated credential.
With those in place, a sandbox reads a short-lived projected token instead of a stored secret, so nothing long-lived ever sits on the machine. The full credential and identity model is under approved actions, and the governance view, including the platform-run OIDC issuer and what you can attest about it, is identity and cloud access; for most local development you will not need any of it, and persistent workspaces and the environment file cover the common cases.
Setting up Local Docker, end to end
Priya wants a fast inner loop. She is iterating on the Insights export service, and every clean sandbox spends two minutes reinstalling dependencies and warming a build before the agent does anything useful. She decides to run the work on her own machine, where the workspace can stick around.
She opens Platform → Sandbox Hosts and registers a Local Docker host named priya-laptop, with the Node and Python families her profiles use. It shows Awaiting operator. She downloads the operator bundle, a small Compose project, drops it on her laptop, and runs the pull-and-up commands the page hands her. Within a few seconds the host flips to Registered and the "last seen" starts ticking. She did not touch a firewall; the operator dialed out on its own.
She sets it as her Local Docker host, so the shared Node 22 . Insights profile, which targets the default Docker host, will land on her laptop when she launches it. Then she turns her attention to the reason she is here: she lets the host keep the workspace between runs. The first sandbox installs and builds as usual; the second mounts the same volume and starts in seconds. The agent's inner loop, which used to pay the setup cost every time, now pays it once. When she finishes the feature, she clears the persistent workspace from the host page to reclaim the disk, and the next run starts clean.
Who can set one up
Registering and managing a Local Docker host rides on hosts.manage, and bringing your own host is gated by an entitlement on your plan, so standing one up is an action for the people your workspace trusts with infrastructure. Everyone with hosts.read can see the hosts that exist and their status. Setting a host as your default Local Docker host is a personal preference rather than an administrative act, so each person chooses their own.
Why Local Docker works this way
A managed sandbox is disposable on purpose, and that is the right default: every run starts from a known state and nothing leaks from the last one. But local development has a different rhythm. The inner loop is tight, the same project over and over, and paying a clean-room setup cost on every iteration is friction with no payoff. Local Docker exists for that rhythm. It runs the same environment your team's profiles describe, on the machine in front of you, and it lets the workspace persist so the loop is fast.
The design keeps the good parts of the managed model while adding the local one. The operator reaches out rather than being reached into, so running it does not mean exposing your machine. The persistent workspace lives on your disk, under your control, so "keep my work between runs" does not mean trusting it to someone else's storage. And because the host is just another target a profile can point at, the same profile your teammates use works on your machine without a separate local configuration to maintain. You get the platform's environment with a local loop's speed, and nothing about it is a second-class version of the real thing.
For an engineer, this is the fast local loop: your Docker Desktop, your persistent workspace, the same profile the team uses, and a sandbox that starts in seconds because it kept its checkout. You stand it up once and forget the operator is there.
For a planner, nothing changes in how you work. A profile that targets the default Docker host runs on whoever launched it; you hand off work the same way, and the engineer on the other end gets their fast local environment.
For a lead, Local Docker is how a team gets a consistent local setup without a setup document that drifts. One profile, each person's own host, the same environment for everyone, and the persistence that makes local iteration quick.
For the person who owns the machine and the boundary, the operator is a well-behaved outbound client: it opens no ports, it holds the workspace on your own disk, and the key that connects it is single-use and rotates on demand. You can run agent work on your own hardware, see exactly what the operator can reach through its health check, and pull its access by stopping it.