Why do I have to periodically use `docker network prune` to reenable docker mapping ip connections inside a container?

A docker network prune deletes any unused networks, and then redeploying the project with something like docker-compose or docker stack deploy will recreate the networks. When docker creates a network, it picks from a pool of private IP’s and excludes any networks it can currently route to. That last part is what is changing when you connect and disconnect from a VPN, or work from a different location with different networks visible to docker.

I suspect what you’re seeing is a network collision. When docker picks the same network subnet that you later find yourself connected to, (e.g. switching on a VPN or wifi at a new location) attempts to connect to that external network from a docker container get routed to the docker network instead the outside network. This results in your connections failing.

You can tell docker to only pick networks from your select pool of subnets. You will need to identify the subnets used by your VPN, home, office, coffee shop, etc, and then select a private IP range outside of any of those subnets for docker. The configuration for this is in the daemon.json file for bridge networks (on Mac, you go to the docker icon, open the settings/preferences, go to Daemon, and then advanced) looks like:

{
  "bip": "10.15.0.1/24",
  "default-address-pools": [
    {"base": "10.20.0.0/16", "size": 24},
    {"base": "10.40.0.0/16", "size": 24}
  ]
}

The “bip” setting is for the bridge IP, aka docker0 or the bridge network named bridge. The bip address must be valid, so don’t end that with a 0 or 255, it will be used for the gateway and the mask (/24) will be used to specify the subnet size.

The “default-address-pools” option came in 18.06 and specifies subnets to use for other bridge networks created by docker, including docker network create bridges and any bridge created by docker-compose.

For swarm mode, starting in 18.09, you can define the pools to use for overlay networks when the swarm is first created with:

$ docker swarm init \
  --default-addr-pool 10.20.0.0/16 \
  --default-addr-pool 10.40.0.0/16 \
  --default-addr-pool-mask-length 24

If you need to change these, you’ll need to delete and recreate the swarm.

To see the networks currently being used, you can run ip r to see all the routes. The first column shows each subnet and mask in CIDR notation. The same notation used by the docker commands above.