39

I cannot execute any command requiring internet connection inside any Docker container.

Works:

docker run ubuntu /bin/echo 'Hello world'

Does not work:

docker run ubuntu apt-get update

Err:1 http://archive.ubuntu.com/ubuntu xenial InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:3 http://archive.ubuntu.com/ubuntu xenial-security InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Reading package lists...
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial-updates/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial-security/InRelease  Temporary failure resolving 'archive.ubuntu.com'

Similar with pip and ping.

I am on Ubuntu 16.04 and not using firewall or corporate proxy server and have tried to restart Docker.

Upd:

Update in interactive mode fails in the same fashion.

docker exec -ti angry_goodall /bin/bash
apt-get update
#fails
ping google.com
#fails with "unknown host" message
ping 8.8.8.8 
# shows PING 8.8.8.8 (8.8.8.8): 56 data bytes
# and than hangs indefinetly

sudo apt-get update runs successfully on host, i.e. on my computer outside docker.

Upd Docker version 1.12.1, build 23cf638

9
  • Can you ping a domain from the host? Can you run apt-get update while in interactive mode with the docker?
    – codaamok
    Oct 3, 2016 at 9:42
  • the output shows the error: Temporary failure resolving 'archive.ubuntu.com' ... try .. ping www.google.com .. see if you get the same response.. then try ... ping 8.8.8.8 ... if IP works, and host name doesn't then your DNS is broken (more /etc/resolv.conf to see what DNS server is being used)
    – TG2
    Oct 3, 2016 at 9:46
  • @adampski, I updated question based on your suggestions. Oct 3, 2016 at 10:04
  • @TG2, I updated question based on your suggestions as well. Oct 3, 2016 at 10:05
  • What version of docker engine are you running?
    – codaamok
    Oct 3, 2016 at 10:26

6 Answers 6

25

As suggested by creack on GitHub issue #866 for Docker:

pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
docker -d

"It will force docker to recreate the bridge and reinit all the network rules"

11
  • 2
    I tried it, and this kills the network on my whole computer.
    – petersohn
    Feb 18, 2017 at 17:14
  • 20
    The -d flag does not exit. Dec 4, 2017 at 15:42
  • 3
    Hi @LuísdeSousa it's a shame you down voted this but consider the possibility that perhaps some switches are removed or altered in newer releases. Especially since this was over a year ago.
    – codaamok
    Dec 12, 2017 at 10:28
  • 11
    instead of only copy/past the command you could explain what these mean :)
    – Adelin
    May 10, 2018 at 9:04
  • 1
    For centos 7 you will need to install these yum install net-tools bridge-utils and start up docker again with systemctl start docker as already stated.
    – oden
    Jan 3, 2019 at 14:16
12

There is a similar issue at StackOverflow where a different solution solves this issue with Docker 17.09 on Ubuntu 16.04:

Check the contents of resolv.conf:

$ cat /etc/resolv.conf

If it includes a line like nameserver 127.0.1.1 it means the containers are obtaining an incorrect names server. To fix this edit the NetworkManager.conf file:

$ sudo pico /etc/NetworkManager/NetworkManager.conf

And comment out the line with dns=dnsmasq; the file should look like this:

[main]
plugins=ifupdown,keyfile,ofono
#dns=dnsmasq

[ifupdown]
managed=false

Finally, restart the network manager:

$ sudo systemctl restart network-manager

Test again the container:

$ docker run ubuntu:16.04 apt-get update
Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB]
Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB]
2
  • My install matched the description and the above approach resolved the issue for me.
    – krcools
    Jan 24, 2018 at 17:47
  • updated answer for Ubuntu 18.04: superuser.com/a/1335054
    – wisbucky
    Jun 28, 2018 at 18:36
12

When you create container using docker run without specifying it's network explicitly (--network foo), docker connects it to default bridge network.

Default bridge network has been deprecated (can't find information, from which version of Docker Engine), should be considered an implementation detail and shouldn't be used.

But, more importantly, any container connected to default bridge network prohibited from networking with outside world - see "Differences between user-defined bridges and default bridge".

You can enable such networking to outside world, but I don't recommend to do so. It requires you to persist suggested host configuration changes, which can be not what you want.

Solution is simple: just create your own (user-defined) bridge network, name it, say, common, and use it explicitly with each one-off container created with docker run:

$ docker network create --driver bridge common
$ docker run -it --network common ubuntu:latest bash
4
  • this one is the answer, today
    – Sebastian
    Jan 29, 2021 at 6:43
  • This is the simple and working solution Feb 2, 2021 at 15:20
  • I can't believe docker keeps this secret so well hidden! One shouldn't have to dig to the fourth SO answer on the fifth page of Google results for a simple question like "get internet access in a container". The linked docs "differences between user-defined bridges and default bridge" do not actually say anything about external network access. The solution does work though; this should be the accepted answer. Is there a better reference?
    – durka42
    Oct 17, 2021 at 0:26
  • Referenced docs no more saying anything about internet access from containers, but they did at the time of writing this answer. I don't have enough time (an will) to dig this problem again and update references, but if you already did that - feel free to edit answer.
    – Anthony
    Oct 17, 2021 at 9:34
8

I've already answered it here: https://stackoverflow.com/a/45644890/

I'm copying the answer below:

First thing to check is run cat /etc/resolv.conf in the docker container. If it has an invalid DNS server, such as nameserver 127.0.x.x, then the container will not be able to resolve the domain names into ip addresses, so ping google.com will fail.

Second thing to check is run cat /etc/resolv.conf on the host machine. Docker basically copies the host's /etc/resolv.conf to the container everytime a container is started. So if the host's /etc/resolv.conf is wrong, then so will the docker container.

If you have found that the host's /etc/resolv.conf is wrong, then you have 2 options:

  1. Hardcode the DNS server in daemon.json. This is easy, but not ideal if you expect the DNS server to change.

  2. Fix the hosts's /etc/resolv.conf. This is a little trickier, but it is generated dynamically, and you are not hardcoding the DNS server.


1. Hardcode DNS server in docker daemon.json

  • Edit /etc/docker/daemon.json

     {
         "dns": ["10.1.2.3", "8.8.8.8"]
     }  * Restart the docker daemon for those changes to take effect:      `sudo systemctl restart docker`
    
  • Now when you run/start a container, docker will populate /etc/resolv.conf with the values from daemon.json.


2. Fix the hosts's /etc/resolv.conf

A. Ubuntu 16.04 and earlier

  • For Ubuntu 16.04 and earlier, /etc/resolv.conf was dynamically generated by NetworkManager.

  • Comment out the line dns=dnsmasq (with a #) in /etc/NetworkManager/NetworkManager.conf

  • Restart the NetworkManager to regenerate /etc/resolv.conf : sudo systemctl restart network-manager

  • Verify on the host: cat /etc/resolv.conf

B. Ubuntu 18.04 and later

  • Ubuntu 18.04 changed to use systemd-resolved to generate /etc/resolv.conf. Now by default it uses a local DNS cache 127.0.0.53. That will not work inside a container, so Docker will default to Google's 8.8.8.8 DNS server, which may break for people behind a firewall.

  • /etc/resolv.conf is actually a symlink (ls -l /etc/resolv.conf) which points to /run/systemd/resolve/stub-resolv.conf (127.0.0.53) by default in Ubuntu 18.04.

  • Just change the symlink to point to /run/systemd/resolve/resolv.conf, which lists the real DNS servers: sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

  • Verify on the host: cat /etc/resolv.conf

Now you should have a valid /etc/resolv.conf on the host for docker to copy into the containers.

3
  • I tried it and it doesn't work Apr 24, 2020 at 17:37
  • "Hardcode DNS server in docker daemon.json" worked Aug 14, 2020 at 6:08
  • Hardcoding in daemon.json works for me. However, it seems better use 8.8.8.8 as primary DNS since it's much faster (in my experience) May 26 at 0:54
1

For me, this seemed to do the trick:

systemctl stop docker

systemctl start docker

(probably systemctl restart docker would have also worked)

0

In my case I had docker installed via snap, after removing it and installing by following instructions from the official website it started to work normally.

Not the answer you're looking for? Browse other questions tagged or ask your own question.