How to Change Docker’s Default 172.17.0.0 Network Range to Avoid IP Conflicts with Captive Portals


3 views

Many developers encounter IP conflicts when Docker's default 172.17.0.0/16 subnet overlaps with:

  • Corporate VPN networks
  • Public WiFi captive portals
  • Existing infrastructure

While modifying /etc/docker/daemon.json with bip changes the docker0 bridge, it doesn't affect:

{
    "default-address-pools": [
        {
            "base": "198.18.0.0/16",
            "size": 24
        }
    ]
}

For Docker 17.12+ (recommended approach):

sudo systemctl stop docker
sudo rm /var/lib/docker/network/files/local-kv.db
sudo nano /etc/docker/daemon.json

Add this configuration:

{
    "bip": "198.18.1.1/24",
    "default-address-pools": [
        {
            "base": "198.18.0.0/16",
            "size": 24
        }
    ]
}

After restarting Docker (sudo systemctl restart docker), verify with:

docker network inspect bridge
docker network create test-net && docker network inspect test-net

To ensure existing projects use the new range without modification:

version: '3.8'
services:
  web:
    image: nginx
    networks:
      - custom-net

networks:
  custom-net:
    driver: bridge
    ipam:
      config:
        - subnet: 198.18.100.0/24
  • Delete existing networks first: docker network prune
  • For Swarm mode, specify during initialization: docker swarm init --default-addr-pool 198.18.0.0/16
  • ICANN recommends 198.18.0.0/15 for testing - perfect for development

If networks still use 172.17.0.0:

  1. Check Docker version (docker --version) - must be 17.12+
  2. Verify no old networks exist (docker network ls)
  3. Ensure no conflicting com.docker.network.bridge.name settings

Many developers encounter network conflicts when Docker's default 172.17.0.0/16 subnet overlaps with existing network infrastructure - particularly problematic with captive portals in public transportation or hotel networks. While modifying docker0 bridge IP via daemon.json helps, it doesn't solve the underlying issue for all Docker networks.

Docker creates three default networks with hardcoded subnets:

$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
abc123         bridge    bridge    local
def456         host      host      local
ghi789         none      null      local

The real issue lies in the default bridge network's immutable configuration.

Here's how to fully reconfigure Docker's networking:

Step 1: Stop Docker Service

sudo systemctl stop docker
sudo systemctl stop docker.socket

Step 2: Remove All Existing Networks

docker network rm $(docker network ls -q)

Step 3: Permanent Configuration via daemon.json

Edit /etc/docker/daemon.json with these advanced parameters:

{
  "bip": "198.18.0.1/16",
  "default-address-pools": [
    {
      "base": "198.18.0.0/16",
      "size": 24
    }
  ],
  "iptables": true,
  "userland-proxy": false
}

After restarting Docker (sudo systemctl start docker), verify the new configuration:

$ docker network inspect bridge | grep Subnet
"Subnet": "198.18.0.0/16"

For existing projects, you can override network settings in compose files:

services:
  web:
    networks:
      custom_net:
        ipv4_address: 198.18.1.2

networks:
  custom_net:
    driver: bridge
    ipam:
      config:
        - subnet: 198.18.0.0/16

Create a custom network template that Docker will use for new networks:

sudo mkdir -p /etc/docker/network
sudo nano /etc/docker/network/default.json

Add this configuration:

{
  "default": {
    "bridge": {
      "com.docker.network.bridge.name": "docker0",
      "ipam": {
        "config": [{"subnet": "198.18.0.0/16"}]
      }
    }
  }
}
  • Port conflicts: Ensure no services bind to 198.18.0.0/16
  • Firewall rules: Update iptables/nftables rules accordingly
  • Legacy containers: Recreate containers after network changes