Cloud Native 12 min read

Enable IPv6 on Docker Bridge and Custom Networks: Step‑by‑Step Guide

This article explains Docker's default bridge network, how to inspect and customize it, and provides detailed procedures for enabling IPv6 on both the default bridge and user‑defined bridge networks, including daemon configuration, sysctl tweaks, ndppd setup, and optional IPv6 NAT.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Enable IPv6 on Docker Bridge and Custom Networks: Step‑by‑Step Guide

Background

Docker treats networking as a core abstraction; a container can join multiple networks. After installation Docker creates three default networks: bridge, host, and none.

NETWORK ID          NAME        DRIVER   SCOPE
11da7fc827b4        bridge      bridge   local
4cd2eae9c4cd        host        host     local
12730ca5beca        none        null     local

The bridge network is the default for docker run. It is implemented by a host‑side docker0 bridge device with a private subnet.

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
    inet6 fe80::xxxx:xx:xx:xxxx/64 scope link

Inspecting the default bridge:

[
  {
    "Name":"bridge",
    "Id":"11da7fc827b4...",
    "Scope":"local",
    "Driver":"bridge",
    "EnableIPv6":false,
    "IPAM":{
      "Driver":"default",
      "Config":[{"Subnet":"172.17.0.0/16","Gateway":"172.17.0.1"}]
    },
    "Options":{
      "com.docker.network.bridge.name":"docker0",
      "com.docker.network.bridge.enable_icc":"true",
      "com.docker.network.bridge.enable_ip_masquerade":"true"
    }
  }
]

Differences Between Default and Custom Bridge Networks

Custom bridges use Docker’s embedded DNS (127.0.0.11) allowing container‑to‑container name resolution; the default bridge does not.

Custom bridges provide better isolation.

Containers can connect/disconnect from a custom bridge at runtime; the default bridge requires recreation.

Custom bridges can be created with a specific Linux bridge; modifying the default bridge requires daemon restart, so custom bridges are recommended for production.

Enabling IPv6 on the Default Bridge

Prerequisite: the host must have a globally routable IPv6 address (not a /128). Verify with ip addr show.

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    inet 10.227.8.141/22 brd 10.227.11.255 scope global eth0
    inet6 2xxx:xxxx::xxxx/64 scope global
    inet6 fe80::xxxx:xxxx:xxxx:xxxx/64 scope link

Edit /etc/docker/daemon.json to enable IPv6 and set a fixed IPv6 subnet (max prefix /80 for the default bridge):

{
  "ipv6": true,
  "fixed-cidr-v6": "2xxx:xxxx::/80"
}

Reload the daemon: sudo systemctl reload docker Verify with docker network inspect bridge; EnableIPv6 should be true and the IPv6 subnet should appear in IPAM.Config.

Potential issues: presence of "live-restore": true in daemon.json or running containers during reload.

Additional steps often required:

Add to /etc/sysctl.conf and apply with sysctl -f to enable NDP proxy on docker0 and the host interface:

# docker0 is Docker's default bridge
net.ipv6.conf.docker0.proxy_ndp=1
# eth0 is the physical NIC (replace as needed)
net.ipv6.conf.eth0.proxy_ndp=1

Install and configure ndppd to forward neighbor discovery messages, or manually add proxy entries per container.

apt-get update -y
apt-get install -y ndppd
cp /usr/share/doc/ndppd/ndppd.conf-dist /etc/ndppd.conf
# Edit ndppd.conf to set proxy eth0 and the IPv6 prefix, then restart:
systemctl restart ndppd

Creating a Custom Bridge with IPv6

Prerequisite: host has an IPv6 address.

Create the network:

docker network create my-net-ipv6 --ipv6 --subnet="2xxx:xxxx::/80"

Verify with docker network inspect my-net-ipv6; EnableIPv6 should be true and the subnet should match.

Run a container on this network:

docker run --network my-net-ipv6 -it busybox ip addr show

Using IPv6 NAT

When containers need private IPv6 addresses or NAT, Docker does not provide built‑in IPv6 NAT. Use the external robbertkl/ipv6nat image:

docker run -d --name ipv6nat --privileged --network host \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -v /lib/modules:/lib/modules:ro \
  robbertkl/ipv6nat

Then create a bridge with a private IPv6 subnet:

docker network create my-net-ipv6 --ipv6 --subnet="fd00:1::1/80" --gateway="fd00:1::1"

Inspect and run containers as before; the containers will receive IPv6 addresses from the private subnet.

Notes

This guide assumes a fresh Docker installation.

IPv6 on the default bridge and on custom bridges behave differently: default bridge uses the host’s global IPv6 prefix (publicly reachable), while custom bridges can use private prefixes.

Original source: https://www.rectcircle.cn/posts/docker-ipv6/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

IPv6container networkingbridge network
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.