RSSAmplifier

xylem | Gordon Beeming · Apr 9, 2026

Setting Up Docker-in-Docker in copilot_here

0
Sign in to vote or save

Gordon Beeming · xylem | Gordon Beeming

This is the practical setup guide. If you want to understand how the broker works under the hood, read the technical deep dive first.

#Enabling the broker

Two ways to get Docker access inside your copilot_here sandbox:

#One-shot flag

Pass --dind to enable the broker for a single session:

The broker starts, creates a socket, mounts it into the container, and tears it down when the session ends. Nothing is persisted.

#Persistent config

Enable the broker for a project so it activates on every run:

This creates .copilot_here/docker-broker.json in your project directory with default settings. From now on, every copilot_here run in this directory starts the broker automatically. No --dind flag needed.

To disable it later:

#Adding allowed images

By default, the image allowlist is empty. That means no containers can be spawned until you explicitly add patterns. You decide what the agent is allowed to pull and run.

#Pattern syntax

Patterns use glob matching where * matches any sequence of characters (including / and :):

PatternMatchesDoesn't match
postgres:16*postgres:16, postgres:16.2, postgres:16-alpinepostgres:15, postgres:latest
mcr.microsoft.com/mssql/server:*Any tag of that imageOther registries
redis:*Any Redis tagbitnami/redis:latest

Keep patterns as specific as possible. postgres:16* is better than postgres:* which is better than *:*. The broader the pattern, the weaker the allowlist.

To remove a pattern:

#Privilege controls

By default, the broker rejects containers that request privileged mode. Some test frameworks or Docker-in-Docker setups need it. You can opt in per-project:

There are also global variants that apply across all projects:

Local settings override global settings.

The privilege toggle only controls HostConfig.Privileged. The broker has four other safety checks that remain active regardless:

  • Host namespace rejection — blocks NetworkMode, PidMode, IpcMode, UsernsMode set to "host"
  • Forbidden bind mounts — blocks mounts targeting /etc, /root, /var, /usr, /bin, /sbin, /proc, /sys, and the Docker socket
  • Dangerous capabilities — blocks SYS_ADMIN, SYS_MODULE, SYS_PTRACE, NET_ADMIN, and others
  • Image allowlist — still applies regardless of privilege settings

#Config file deep dive

The broker configuration is a JSON file. Here's a fully annotated example:

#Field reference

FieldDefaultPurpose
enabledfalseWhether the broker activates automatically (without --dind)
inherit_default_rulestrueMerge with the 65 built-in endpoint rules. Set to false to use only your custom endpoints
mode"enforce""enforce" blocks disallowed requests. "monitor" logs but forwards everything
enable_loggingfalseWrite decisions to ~/.copilot_here/logs/docker-broker.jsonl
body_inspection.reject_privilegedtrueBlock Privileged: true
body_inspection.reject_host_namespacestrueBlock NetworkMode/PidMode/IpcMode/UsernsMode: "host"
body_inspection.reject_forbidden_bindstrueBlock mounts to sensitive host paths
body_inspection.reject_dangerous_capabilitiestrueBlock dangerous Linux capabilities
body_inspection.allowed_images[]Glob patterns for allowed container images
allowed_endpoints[]Custom endpoint rules (merged with defaults if inherit_default_rules is true)

#Config resolution order

  1. Local.copilot_here/docker-broker.json in the project directory
  2. Global~/.config/copilot_here/docker-broker.json
  3. Embedded defaults — compiled into the binary (65 endpoint rules, all safety checks enabled, empty image list)

Local overrides global, global overrides embedded. When inherit_default_rules is true, your custom endpoints merge with the defaults. You only need to add new ones or override existing ones.

#Using with Airlock

DinD and Airlock can work together. When combined, the setup changes:

  • The proxy container runs a socat bridge that forwards Docker API calls to the host broker
  • The app container's DOCKER_HOST points at tcp://proxy:2375 instead of a Unix socket
  • Sibling containers spawned by the agent get their NetworkMode rewritten to join the airlock network
  • Siblings are reachable via Docker DNS and network-isolated. They can't bypass the proxy

If you're already using Airlock, adding --dind (or enabling the broker in config) is all you need. The compose template handles the rest automatically.

Known limitation: Testcontainers and similar frameworks that connect to siblings via host-mapped ports (e.g., host.docker.internal:32768) won't work in airlock mode yet (#101). The airlock's internal: true network blocks those connections. Use --dind without airlock as a workaround. The broker still enforces all API rules, you just lose the HTTP proxy network isolation.

#Viewing and editing rules

--show-docker-broker-rules outputs the fully resolved configuration after merging all layers, so you can verify what's actually active.

#Common patterns

#Testcontainers with .NET

Testcontainers needs Ryuk (its resource reaper) plus whatever database images your tests use. Set up once with persistent config, then your normal interactive sessions have Docker access:

The agent can run your integration tests during the conversation and Testcontainers will work. You can also verify the setup with a one-shot: copilot_here --dind --dotnet -p "run the integration tests".

#Postgres for integration tests

If you don't want persistent config, use --dind for a one-off session:

#Multiple services

Some test suites need several containers. Add each image you need:

#Monitor mode

If you want to see what Docker calls the agent makes before enforcing rules:

This logs every decision to ~/.copilot_here/logs/docker-broker.jsonl but forwards all requests. Good for understanding what your test suite actually needs before locking it down.

#Wrapping up

The brokered Docker socket is currently in beta. The defaults are conservative: empty image list, all safety checks on, enforce mode. Start with the minimum set of images your workflow needs and expand from there.

For the technical details on how the broker intercepts and inspects requests, read the deep dive post. For the quick overview, check the copilot_here site.

Gordon Beeming

Gordon Beeming

Father • Husband • Triathlete • SSW Solution Architect

Read the original on gordonbeeming.com

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.