A quick post about a problem I faced while building a Docker container on a VM without IPv6 and how I solved it.

The situation

  • You have a server that is configured without IPv4 internet access (IPv6 only).
  • You want to build a Docker image, which requires downloading external resources.
  • The download server is configured as dual-stack (both IPv4 and IPv6).

In my case I tried to build a go binary, which failed after a while with a timeout (additional linebreaks added for readability):

Code
go: github.com/labstack/echo/v4@v4.11.4:
  Get "https://proxy.golang.org/github.com/labstack/echo/v4/@v/v4.11.4.mod":
  dial tcp: lookup proxy.golang.org on 8.8.4.4:53:
  read udp 172.17.0.2:33655->8.8.4.4:53: i/o timeout
The command '/bin/sh -c go mod download' returned a non-zero code: 1

In theory the request should be successful, as the server supports IPv6:

Bash
root@vm:~# host proxy.golang.org
proxy.golang.org has address 216.58.206.49
proxy.golang.org has IPv6 address 2a00:1450:4001:827::2011

Even weirder, the error has nothing to do with the target: It fails talking to Google DNS (8.8.4.4). But why?

The cause

Docker creates its own separate IPv4-based NAT network for the build container, making it believe it has IPv4 internet access. However, since the NAT gateway doesn't support this and doesn't translate it to IPv6 (NAT46), the connection just ends up timing out.

The solution

When running docker build, use the host's network directly instead of creating a separate network namespace:

Bash
docker build --network=host ...

As container builds are temporary and generally done on separated CI/CD systems, this should not create security problems.