After months of letting an AI coding agent manage a local development stack, developer alegauss discovered a persistent bottleneck: the agent consistently failed at Docker tasks. The issue isn't the model's intelligence, but Docker's interface, which was designed for humans with context, browsers, and intuition, not for agents that only see stdout after a process exits and pay for every byte of output.

Port Conflicts and Allowlist Blind Spots

The first major friction point occurs when a port is already allocated. The Docker daemon throws an error stating 'Bind for 0.0.0.0:8080 failed: port is already allocated,' but it names no culprit. An agent, lacking OS context, often guesses by changing the port or restarting the engine, leading to confusion. The fix is to instruct the agent to run lsof -iTCP:8080 -sTCP:LISTEN (on Linux/macOS) or use PowerShell's Get-NetTCPConnection to identify the process holding the port before editing configuration files. Additionally, standard allowlists fail because Docker commands like docker ps (read) and docker rm (write) share the same binary prefix. Agents must be restricted to pure read commands like docker ps, docker logs, and docker inspect, with manual approval required for any write operations.

Token Sinks and False Readiness

Logs represent the largest token sink in agent sessions. A container in a crash loop generates repeated stack traces, and docker logs dumps all of them into the context window. To avoid wasting tokens on repetition, alegauss recommends redirecting logs to a file (docker logs api > .agent/api.log) and using grep to extract only error-related lines. Furthermore, agents often mistake a container's 'Up' status for a working service. A container can be running but bound to 127.0.0.1 instead of 0.0.0.0, or stuck in migrations. Agents must be instructed to use explicit readiness checks, such as timeout 60 bash -c 'until curl -sf http://localhost:8080/health; do sleep 2; done', rather than relying on docker ps status alone.

The Cleanup Crisis

The final pain point is cleanup. After a debugging session, an agent may leave behind six containers, two networks, and a volume. Standard docker prune commands are dangerous because they affect the whole machine, potentially deleting important data volumes. The solution is labeling at creation time (--label agent.session=repro-17) and scoping cleanup commands to those labels. This ensures that only the agent's temporary scaffolding is removed, leaving persistent volumes like Postgres intact. The core pattern behind all five failures is that Docker doesn't perform the 'joins' a human does intuitivelyβ€”connecting daemon errors to OS state, or command syntax to intent.

Key Takeaways

  • Docker's CLI is optimized for humans with context, not agents with limited visibility.
  • Agents must use OS-level tools (lsof, Get-NetTCPConnection) to diagnose port conflicts.
  • Log redirection and grep filtering prevent massive token waste from crash loops.
  • Explicit health checks are required because 'running' does not equal 'answering'.
  • Label-based cleanup prevents accidental deletion of persistent volumes.

The Bottom Line

Stop blaming the LLM for Docker failures. The bottleneck is the interface, and fixing it requires explicit, rule-based instructions that bridge the gap between Docker's daemon view and the OS reality.

Source

DEV.to: Your coding agent is bad at Docker, and it isn't the agent's fault