Binding to `localhost` inside a container fails because ::1 doesn't exist
- [x] This is a bug report
- [ ] This is a feature request
- [x] I searched existing issues before opening this one
Expected behavior
Programs should be able to safely bind to localhost to create listening sockets inside docker. In particular localhost should always resolve to a valid loopback address.
Either ::1 should exist as a loopback address or /etc/hosts should NOT contain a reference to ::1 localhost.
Actual behavior
By default (without enabling any IPv6 support) containers have a hosts file (/etc/hosts) which looks like this:
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.8 158872fd16d1
But it does not add ::1 as an IP address on the loopback device:
# ip address show lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
As a result software attempting to bind to localhost and fails because localhost resolved to ::1 and ::1 is not an address inside the container.
A concrete example; this happens when using python asyncio's create_server (manual page). This call should basically never fail, and yet it always fails inside a docker container:
await asyncio.get_running_loop().create_server(callback, "localhost")
Error:
OSError: [Errno 99] error while attempting to bind on address ('::1', 0, 0, 0): cannot assign requested address
Steps to reproduce the behavior
Output of docker version:
Client:
Version: 20.10.7
API version: 1.41
Go version: go1.15.14
Git commit: f0df350
Built: Wed Nov 17 03:05:36 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server:
Engine:
Version: 20.10.7
API version: 1.41 (minimum version 1.12)
Go version: go1.15.14
Git commit: b0f5bc3
Built: Wed Nov 17 03:06:14 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.6
GitCommit: d71fcd7d8303cbf684402823e425e9dd2e99285d
runc:
Version: 1.0.0
GitCommit: 84113eef6fc27af1b01b3181f31bbaf708715301
docker-init:
Version: 0.19.0
GitCommit: de40ad0
Output of docker info:
Client:
Context: default
Debug Mode: false
Server:
Containers: 263
Running: 2
Paused: 0
Stopped: 261
Images: 5
Server Version: 20.10.7
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc io.containerd.runc.v2 io.containerd.runtime.v1.linux nvidia
Default Runtime: runc
Init Binary: docker-init
containerd version: d71fcd7d8303cbf684402823e425e9dd2e99285d
runc version: 84113eef6fc27af1b01b3181f31bbaf708715301
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 4.14.268-205.500.amzn2.x86_64
Operating System: Amazon Linux 2
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 3.793GiB
Name: ip-10-20-11-38.ap-southeast-2.compute.internal
ID: BEL3:HYJB:BHSZ:U6CB:FHPP:YNM7:K3RN:J63K:VQBX:RYE7:IM7Q:J2AZ
Docker Root Dir: /var/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
This was running docker as an AWS ECS instance.
Any solutions?
I just ran into the same issue. Just use the local adapter loopback-ip: 127.0.0.1. For some reason localhost resolves to a ipv6 address. I don't know why this is not addressed really.
@mrdobalina2k Few things to note:
- This issue was fixed in v26.0. See https://docs.docker.com/engine/release-notes/26.0/#bug-fixes-and-enhancements-2.
- Prior versions are EOL'd -- if you're using an outdated version, please upgrade.
- If your containerized process binds to both IPv4 and IPv6 and you want to bind only to the IPv4 loopback address, you need to use
docker run --sysctl=net.ipv6.conf.all.disable_ipv6=1to disable IPv6 altogether. - This is a legacy issue tracker and is kept only because archiving this repo would make all issues read-only. If you encounter an issue with Docker Engine, you should file an issue against https://github.com/moby/moby. If you encounter an issue with Docker Desktop, you should file an issue against either https://github.com/docker/for-mac or https://github.com/docker/for-win.
I'm going to close this issue as it's been fixed by https://github.com/moby/moby/pull/47062.