Docker 514 networks are IPv4-only unless you ask. --ipv6 makes a user-defined network dual-stack, and with no IPv6 subnet given, Docker allocates a /64 from a unique local address (ULA) range under fd00::/8. Current Engine versions also build IPv6-only networks with --ipv4=false:
docker network create --ipv6 l3-v6
docker network inspect l3-v6 --format '{{json .IPAM.Config}}' | cut -c 1-90
docker run -d --name l3-v6a --network l3-v6 alpine:3 sleep 300
docker run --rm --network l3-v6 alpine:3 ping -6 -c 1 l3-v6a | head -2
docker network create --ipv6 --ipv4=false l3-v6only
docker run --rm --network l3-v6only alpine:3 ip addr show eth0 | grep inet66dac146a2b13836ad4ae2559f2b10d8da5adfc839f85d638ead822a7ad51ea7
[{"Subnet":"172.21.0.0/16","Gateway":"172.21.0.1"},{"Subnet":"fdbd:3765:91a7::/64","Gatewa
c70630ffe3cca4f43cdc535f5e53d05e504159ed729f1c78d3f9a2cf2410ab88
PING l3-v6a (fdbd:3765:91a7::2): 56 data bytes
64 bytes from fdbd:3765:91a7::2: seq=0 ttl=64 time=0.301 ms
fa8cec08dbf686787e54d975945cc4701f27abde820a721d83a5144fd6a2b9d1
inet6 fdbd:3765:91a7:1::2/64 scope global flags 02
inet6 fe80::84e8:cff:fe4c:4c47/64 scope link tentativeThe embedded DNS server returned l3-v6a's IPv6 address, and the IPv6-only container has no IPv4 inet line. ULA addresses are private, so Docker translates outgoing IPv6 with NAT just as it does IPv4, and published ports also listen on the host's IPv6 addresses (the [::]:33000 line in Publishing Ports to the Host). With routable global prefixes, assign a real --subnet and set -o com.docker.network.bridge.gateway_mode_ipv6=routed to route without translation. A server listening on 0.0.0.0 accepts IPv4 only; Node.js 2,131 listens on :: by default, so BookNest needs no change. Finally, clean up: docker rm -f -v l3-db l3-api l3-v6a and docker network rm l3-booknest l3-custom l3-internal l3-v6 l3-v6only.