Claude Code should be network-aware when generating Docker Compose configurations

Resolved 💬 8 comments Opened Mar 26, 2026 by digin1 Closed Apr 26, 2026

Problem

When asked to create a Docker-based application, Claude Code generates docker-compose.yml files with default networking and common ports without checking the host system's network state. This can cause serious issues on local/server environments.

1. Docker network IP range conflicts

  • Docker's default bridge networks pick IP ranges (typically 172.17.0.0/16, 172.18.0.0/16, etc.) that can collide with:
  • NFS / CIFS / SMB mounted volumes (e.g., //192.168.x.x/share or 172.x.x.x ranges)
  • VPN tunnels (corporate VPNs often use 172.16.0.0/12 or 10.x.x.x)
  • Overlay networks, Tailscale, WireGuard, etc.
  • Host routes to other machines on the LAN
  • When a Docker network claims an IP range that overlaps a mount point or route, the mount silently breaks — traffic gets routed to the Docker bridge instead of the actual server.

2. Port conflicts — destructive behavior

  • Claude Code tends to assign common ports (3000, 5432, 8080, 6379, etc.) and when those are already in use, it may kill the existing process or suggest --force-recreate without understanding what's running.
  • On a developer's machine, port 3000 might be another project, a monitoring tool, or a production-adjacent service.

3. No system awareness when running locally

  • The web/API version doesn't control the host, so this is less critical there. But when Claude Code runs as a local CLI tool with shell access, it has the ability (and should use it) to inspect the host before generating configs.

4. Tunnel vision — no awareness of coexisting projects and services

  • Claude Code is hyper-focused on the current project and has zero awareness of other applications, services, or Docker stacks already running on the same machine.
  • A developer's machine typically runs multiple projects simultaneously — other Docker Compose stacks, local databases, dev servers, background services. Claude Code treats the system as if only the current project exists.
  • This leads to it confidently assigning ports already used by other projects, creating networks that overlap with other stacks, and killing processes that belong to unrelated but important services.
  • This is fundamentally a system-level awareness gap. Yes, scanning the system state costs tokens, but a lightweight pre-flight strategy can be devised:
  • A one-time system snapshot at session start (active ports, Docker networks, mounts, routes) cached for the session — costs tokens once, prevents repeated conflicts.
  • A docker.systemProfile setting where users can declare known services/ports/subnets, so Claude Code doesn't need to discover them every time.
  • A lightweight check before any docker compose up or port-binding action — just ss -tlnp and docker network ls is a few hundred tokens at most, far cheaper than debugging a broken NFS mount or killed service.
  • The tradeoff is small (a few hundred extra tokens per session) vs. the cost of silently breaking other running services.

5. Known Claude Code behavioral patterns (self-observed)

These are patterns observable in how the model currently handles Docker tasks:

  1. Kill-first instinct on port conflicts — When docker compose up fails due to a port conflict, Claude Code's go-to move is lsof -i :3000kill -9 <pid> rather than reassigning the port in the compose file or asking the user. This is destructive by default.
  1. Never checks docker ps before spinning up — Claude Code doesn't look at already-running containers before creating new ones. Two projects can end up with conflicting container names, port mappings, or network ranges.
  1. Ignores /etc/docker/daemon.json — Users may have configured custom default address pools there. Claude Code never reads this, so it can't respect existing network allocation strategies.
  1. No awareness of docker network prune risks — When troubleshooting, Claude Code may suggest docker network prune without realizing it will tear down networks used by other running stacks.
  1. Boilerplate port choices — The model gravitationally defaults to 3000 (frontend), 8000/8080 (backend), 5432 (postgres), 6379 (redis), 27017 (mongo) — the most commonly conflicting ports on any dev machine. It rarely picks non-standard ports proactively.
  1. No compose project isolation awareness — Docker Compose uses the directory name as the project name by default. Claude Code doesn't check if another stack already uses the same project name prefix, which can cause resource collisions.
  1. Treats the machine as a blank slate — This is the core issue. The model has no "system mental model." Every task starts from the assumption that nothing else exists on the host. This is fine for a sandboxed cloud environment but actively harmful on a developer's daily machine.

Expected Behavior

When generating Docker Compose files on a local system, Claude Code should:

  1. Check existing network routes before creating Docker networks:
  • ip route / route -n to see active routes
  • docker network ls + docker network inspect to see existing Docker networks
  • mount | grep -E 'nfs|cifs|smb' or findmnt to detect network mounts
  • ss -tlnp / netstat -tlnp to check port usage
  1. Define explicit, non-conflicting subnets in docker-compose:

```yaml
networks:
app-net:
driver: bridge
ipam:
config:

  • subnet: 10.200.0.0/24 # chosen to avoid conflicts

```

  1. Avoid killing existing processes on ports — instead, pick alternative ports or ask the user.
  1. Respect user networking preferences — ideally via a setting in Claude Code config (e.g., preferred Docker subnet range, reserved port ranges).
  1. Build a lightweight system context — a cached snapshot of active services, ports, networks, and mounts that informs all infrastructure decisions during the session.

Suggested Implementation

  • Add network-awareness checks to Claude Code's Docker generation behavior (system prompt / tool-use guidance)
  • When running locally, run pre-flight checks before writing docker-compose.yml
  • Expose optional settings like:
  • docker.preferredSubnet: e.g., "10.200.0.0/16"
  • docker.reservedPorts: e.g., [3000, 8080]
  • docker.systemProfile: user-declared list of known services and their ports/subnets
  • Cache a lightweight system snapshot at session start to avoid repeated discovery cost
  • Train future models to treat the host as a shared environment, not a blank slate

Environment

  • Affects: Claude Code CLI (local execution)
  • Severity: Can silently break network mounts, VPNs, kill unrelated services

View original on GitHub ↗

This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗