{"slug": "zed-editor-docker-agent-acp-but-in-a-sandbox-running-the-agent-with-sbx", "title": "Zed Editor, Docker Agent, ACP, but in a sandbox: running the agent with sbx", "summary": "Docker's sbx sandboxes can run Docker Agent in an isolated microVM while Zed connects to it over the ACP protocol, with llmman still serving the model on the host GPU, according to a hands-on write-up. The only configuration change required is switching the provider's base_url from http://127.0.0.1:17434/v1 to http://host.docker.internal:17434/v1 in a copied sbx.llmman.docker-agent.yaml file. The setup limits the agent's blast radius to the shared workspace and network policy, and keeps API keys and GitHub tokens out of the sandbox via sbx secret set proxy injection.", "body_md": "# Zed Editor + Docker Agent + ACP, but in a sandbox: running the agent with sbx\n\n## [In two minutes](#in-two-minutes)\n\nIn [the previous article](https://k33g.org/p/20261003-acp-zed-docker-agent), I showed you how to plug **[Zed](https://zed.dev/)** into **[Docker Agent](https://docker.github.io/docker-agent/)** thanks to the **[ACP](https://agentclientprotocol.com/get-started/introduction)** protocol, with **[llmman](https://llmmanorg.github.io/)** serving the model locally.\n\nIt works very well, but there's one \"small\" detail: the agent runs **directly on my machine**. And it's allowed to use the `shell`... 😬\n\nSo today, we're going to do the same thing, but by running **Docker Agent inside a Docker sandbox (sbx)**, and connecting Zed to the agent in that sandbox. And you'll see, there's almost nothing to change.\n\nHere's a summary of my setup for this article:\n\n## [Quick reminder: what is sbx?](#quick-reminder-what-is-sbx)\n\n**[sbx](https://docs.docker.com/ai/sandboxes/)** (Docker Sandboxes) is Docker's tool for running code agents (Claude Code, Codex, Gemini, Docker Agent, your own handmade agent...) in **isolated sandboxes**, based on microVMs:\n\n- the agent only sees **the working directory** (the workspace) you share with it, mounted at the same path as on your machine,\n- it has no access to the rest of your file system (your SSH keys, your other projects, ...),\n- outbound network traffic goes through a **proxy** with a network policy: by default, the agent can't reach just anything,\n- this same proxy **protects your secrets** (API keys, GitHub tokens, ...): you declare them on the host with`sbx secret set` , and the proxy injects them into outgoing requests. The keys are never present inside the sandbox, so the agent can neither read them nor leak them,\n- it even has its own Docker daemon, so it can run containers without touching the ones on your machine.\n\n### [Why is it important to run an agent in a sandbox?](#why-is-it-important-to-run-an-agent-in-a-sandbox)\n\nA code agent is a program that **decides on its own** which commands it's going to run. In my setup, the agent has access to the `shell` toolset, and it's driven by a \"small\" local model. Even though Zed asks me for confirmation before each command, all it takes is a moment of inattention (or a prompt injected into a project file) for a misplaced `rm -rf` or a `curl` to an unknown server to get executed.\n\nAnd on your machine, the agent also has access to your environment variables and your config files: a simple `env` or `cat ~/.config/...` and your API keys end up in the model's context (or worse, sent somewhere else).\n\nWith a sandbox, the \"blast radius\" is limited to the workspace and to what the network policy allows, and your secrets stay out of the agent's reach. So you keep all the power of the agent, without handing it the keys to the whole house.\n\n## [Setup](#setup)\n\n### [llmman, still on the host](#llmman-still-on-the-host)\n\nNothing changes on that side: **llmman** keeps running on my machine (and therefore keeps using my GPU):\n\n```\nllmman serve\n```\n\nFor installing and downloading the model, see [my dedicated article](https://k33g.org/p/20261001-llmman) and [the previous article](https://k33g.org/p/20261003-acp-zed-docker-agent).\n\n### [Adapting the Docker Agent configuration](#adapting-the-docker-agent-configuration)\n\nI created a copy of my configuration file: `sbx.llmman.docker-agent.yaml`. The **only** thing that changes is the `base_url` line:\n\n```\nproviders:\n  llmman:\n    api_type: openai_chatcompletions\n    #base_url: http://127.0.0.1:17434/v1\n    base_url: http://host.docker.internal:17434/v1\n    \nagents:\n\n  root:\n    model: mellum\n    description: A local code agent, powered by a small LLM.\n    instruction: |\n      Your name is Riker. You are a developer expert.\n      You act as a mentor and coding partner. \n\n      # Tool discipline\n\n      Built-in tools:\n      - shell: use the `shell` tool to explore the project, read files, or run commands.\n        Chain commands as long as it is useful, then give a clear final answer.\n\n      # Style\n\n      Be concise. Prefer a small, correct, compilable example over prose.\n\n    toolsets:\n      - type: shell\n\nmodels:\n  mellum:\n    provider: llmman\n    model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M\n```\n\nWhy? Because the sandbox has **its own `localhost`**: inside it, `127.0.0.1` refers to the sandbox itself, not my machine. To reach **llmman** running on the host, we go through `host.docker.internal`.\n\n### [Creating the sandbox](#creating-the-sandbox)\n\nFrom the project directory, a single command:\n\n```\nsbx create docker-agent . --name docker-agent-acp\n```\n\n- `docker-agent` : the agent to use in the sandbox,\n- `.` : the current directory, which becomes the workspace shared with the sandbox,\n- `--name docker-agent-acp` : the name of the sandbox, which we'll need for the Zed configuration.\n\n💡 If the agent can't reach **llmman** (request blocked by the proxy), you need to allow the port in the network policy, on your machine: `sbx policy allow network localhost:17434`. The `sbx policy log` command lets you see what was blocked and why.\n\n### [Declaring the agent in Zed](#declaring-the-agent-in-zed)\n\nIn Zed's settings (`settings.json`), we add a new agent to the `agent_servers` section. This time, it's no longer `docker-agent` that Zed launches directly, but `sbx exec`, which will run `docker-agent serve acp` **inside** the sandbox:\n\n```\n\"agent_servers\": {\n  \"🤖 docker-agent (sbx llmman)\": {\n    \"type\": \"custom\",\n    \"command\": \"sbx\",\n    \"args\": [\n      \"exec\",\n      \"-i\",\n      \"docker-agent-acp\",\n      \"docker-agent\",\n      \"serve\",\n      \"acp\",\n      \"/Users/k33g/kDrive/Rickub/demo-docker-agent-acp/sbx.llmman.docker-agent.yaml\"\n    ]\n  }\n}\n```\n\nA few remarks:\n\n- the `-i` is**essential** : ACP goes through`stdin` /`stdout` , so standard input must stay open between Zed and the sandbox,\n- `docker-agent-acp` is the name of the sandbox we just created,\n- the path to the YAML file is the same as on my machine, since the workspace is mounted **at the same path** in the sandbox.\n\nObviously, adapt the sandbox name and the path to your own configuration file.\n\n### [Let's go](#lets-go)\n\nOpen Zed's agent panel, pick **\"🤖 docker-agent (sbx llmman)\"** from the list of available agents, and it's exactly the same experience as in the previous article: the agent explores your project, reads files, runs shell commands... except that all of this happens **inside the sandbox**. Files modified by the agent in the workspace of course show up directly in Zed, since it's the same directory.\n\n## [To sum up](#to-sum-up)\n\n- **Zed** launches the agent in the sandbox with`sbx exec -i` , and talks to it over**ACP** (JSON-RPC over stdio).\n- **Docker Agent** runs**isolated** in the**sbx** sandbox, with only the project workspace.\n- **Docker Agent** \"talks\" to the**OpenAI API** served by**llmman** on the host via`host.docker.internal` , going through the sandbox proxy.\n- This proxy filters the network and injects secrets when needed (API keys, ...) without the agent ever seeing them.\n- On the configuration side: one YAML line changed for the **llmman** endpoint and one entry in Zed's settings. That's it.\n\nThere you go, with next to nothing, we keep the same \"100% local\" setup as in the previous article, but with an agent that can no longer do whatever it wants on your machine. Feel free to ask questions 🙂\n\nWritten by\n\nKeep reading\n\n### Zed Editor + Docker Agent + ACP: coding with a local agent plugged into llmman\n\nPlug Zed's agent panel into Docker Agent over ACP, then point it at llmman to chat with a fully local, OpenAI-compatible coding agent.\n\nOct 3, 2026\n\n### Embedding a Web IDE and Docker Agent into `sbx`, a fully secured sandbox\n\nEmbed a web IDE and docker-agent into an sbx sandbox with Docker Model Runner for a ready-to-use secure dev environment.\n\nApr 18, 2026\n\n### Using `docker-agent` with Docker Model Runner and `sbx`\n\nRun docker-agent fully secured inside an sbx sandbox while it talks to Docker Model Runner for local inference.\n\nApr 3, 2026", "url": "https://wpnews.pro/news/zed-editor-docker-agent-acp-but-in-a-sandbox-running-the-agent-with-sbx", "canonical_source": "https://k33g.org/p/20261004-acp-sbx-docker-agent", "published_at": "2026-10-07 17:36:25+00:00", "updated_at": "2026-10-07 17:50:13.290783+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "agent-protocols", "ai-infrastructure"], "entities": ["Zed", "Docker Agent", "sbx", "Docker", "Agent Client Protocol", "llmman", "Claude Code", "Codex"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/zed-editor-docker-agent-acp-but-in-a-sandbox-running-the-agent-with-sbx", "markdown": "https://wpnews.pro/news/zed-editor-docker-agent-acp-but-in-a-sandbox-running-the-agent-with-sbx.md", "text": "https://wpnews.pro/news/zed-editor-docker-agent-acp-but-in-a-sandbox-running-the-agent-with-sbx.txt", "jsonld": "https://wpnews.pro/news/zed-editor-docker-agent-acp-but-in-a-sandbox-running-the-agent-with-sbx.jsonld"}}