53

Can somebody help me get apt-get working in my docker container? Whenever I try running any apt-get command in my docker container, the command fails. I'm running Docker version 1.1.1, build bd609d2 on ubuntu 12.04.

When I do

$ sudo docker run -i -t ubuntu:14.04 /bin/bash
# apt-get update

I get errors saying

Could not resolve 'archive.ubuntu.com'

I tried uncommenting the line below in /etc/default/docker

DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"

but I still can't ping google.com

ping: unknown host

I confirmed that the container is using the dns servers 8.8.8.8 and 8.8.4.4

root@0baa87fc6322:/# cat /etc/resolv.conf

nameserver 8.8.8.8

nameserver 8.8.4.4

and I'm able to ping both servers so I'm pretty sure that a firewall isn't just dropping my packets.

Any help with this would be appreciated!

Thanks!

Henke
  • 4,445
  • 3
  • 31
  • 44
jbadua
  • 1,069
  • 1
  • 8
  • 9
  • if a firewall prohibits using an external recursive nameserver, then use the recursive nameserver or caching forwarder available to machines on your LAN. I suppose if you could reconfigure the firewall, you had done so by now, means you're not in a position to change that. Confirm whether it's a firewall using dig @8.8.8.8 google.com, see whether that resolves. if it does, it's not firewall. – Deleted User Jul 18 '14 at 20:55
  • Solved problem by switching away from Google's DNS servers to Cloudflare's @`1.1.1.1` & `1.1.4.4` – NerdOfCode Aug 27 '18 at 20:22
  • 2
    Does this answer your question? [Network calls fail during image build on corporate network](https://stackoverflow.com/questions/24151129/network-calls-fail-during-image-build-on-corporate-network) – Ian Kemp Apr 09 '21 at 14:07

10 Answers10

42

Thanks for all your help! I found out it was a dns problem and that it was because of a firewall. After searching some more I found this question that I wasn't able to find while searching 'docker apt-get fail'

Docker - Network calls fail during image build on corporate network

His problem was similar to mine and the solution helped me get it working. I've copied over his solution for anybody that finds this question in the future.

Those Google servers weren't accessible from behind our firewall, which is why we couldn't resolve any URLs.

The fix is to tell Docker which DNS servers to use. This fix depends on how you installed Docker: Ubuntu Package

If you have the Ubuntu package installed, edit /etc/default/docker and add the following line:

DOCKER_OPTS="--dns <your_dns_server_1> --dns <your_dns_server_2>"

You can add as many DNS servers as you want to this config. Once you've edited this file you'll want to restart your Docker service:

sudo service docker restart

Binaries

If you've installed Docker via the binaries method (i.e. no package), then you set the DNS servers when you start the Docker daemon:

sudo docker -d -D --dns --dns &

Community
  • 1
  • 1
jbadua
  • 1,069
  • 1
  • 8
  • 9
  • 3
    For those who don't know what's your dns is https://robinwinslow.uk/2016/06/23/fix-docker-networking-dns/ – Avinash Raj Sep 18 '17 at 05:46
  • 2
    FYI, this answer (etc/default/docker) is for older versions of Ubuntu that use Upstart. Since Ubuntu 16.04, it is using systemd, so you will need to follow https://stackoverflow.com/a/51089399 instead. – wisbucky Jun 28 '18 at 18:41
28

If you see an error like Could not resolve ..., it is likely a DNS configuration.

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.

wisbucky
  • 33,218
  • 10
  • 150
  • 101
  • Work for me. :) – Him Hah Jul 27 '18 at 10:46
  • On Ubuntu 18.04, /etc/resolv.conf is using 127.0.0.53 but it is not a symlink in my case. – gtato Sep 26 '18 at 16:09
  • @wisbucky Please explain how did you get the DNS array 1st value. it is random or how we may get this("10.1.2.3") value. – dinu0101 Oct 18 '18 at 07:24
  • @dinu0101 You have to know the DNS server that the host is using (which is a separate question). You could try running `nslookup google.com`, and the first line `Server:` should be it. – wisbucky Oct 18 '18 at 16:31
  • I'm using a vmware ubuntu18.04 in a company's workstation and the 2nd - B option works for me. Thanks! – Tran Triet Nov 12 '18 at 02:01
10
$ sudo docker run -i -t --net=host ubuntu /bin/bash
# apt-get update

No errors! - Note the added --net=host.


Below I show how to reproduce the error.
I did the following on a clean machine having nothing but Ubuntu 18.04 installed on it.

First install docker. Copy-paste one line at a time and hit Enter after each line:

sudo apt update                         # took 11 seconds for me
sudo apt install -y apt-transport-https ca-certificates \
curl software-properties-common

The second of the two commands above (one command broken up on two lines) is optional and took ~20 seconds for me.

echo "cacert=/etc/ssl/certs/ca-certificates.crt" >> ~/.curlrc
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
| sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://\
download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

The command above took ~7 seconds for me.

sudo apt update                         # ~3 seconds this time
sudo apt install -y docker-ce           # ~1 minute for me

Optional -- if you don't like to prefix docker with sudo every time:

sudo usermod -aG docker ${USER}

Log out and back in.
Confirm that docker is now added to your groups:

id -nG

Now to the core part of interest:

$ sudo docker run -it ubuntu /bin/bash  # ~10 seconds for me
# apt update                            # first Err after ~1 minute
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
  Connection failed [IP: 91.189.88.152 80]
Err:2 http://security.ubuntu.com/ubuntu focal-security InRelease
  Connection failed [IP: 91.189.88.152 80]
Err:3 http://archive.ubuntu.com/ubuntu focal-updates InRelease
  Connection failed [IP: 91.189.88.152 80]
Err:4 http://archive.ubuntu.com/ubuntu focal-backports InRelease
  Connection failed [IP: 91.189.88.152 80]
...
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease [...]
...
W: Some index files failed to download. They have been ignored, [...]

Note how I just recreated the error described by the OP!
The OP got Could not resolve 'archive.ubuntu.com',
while I got Failed to fetch http://archive.ubuntu.com.
But the root cause is the same: the docker container has no access to the internet.

I don't want to stay in this bad docker container so I hit Ctrl + D.
No wish to keep it either, so I do:

sudo docker container ps -a

which tells me that the CONTAINER ID in my case is c05ec98236f0.

I remove this container:

sudo docker container rm c05ec98236f0

Heads up for something that doesn't give me an error.

$ sudo docker run -it --net=host ubuntu bash
# apt update                            # ~7 seconds
Get:1 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
...
Fetched 16.4 MB in 4s (4332 kB/s)
Reading package lists... Done
Building dependency tree
Reading state information... Done
3 packages can be upgraded. Run 'apt list --upgradable' to see them.

Voilà! No error!

References:
https://askubuntu.com/questions/1162163#1162198
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04
https://stackoverflow.com/questions/3160909#31424970
https://stackoverflow.com/questions/43316376#43317607

Henke
  • 4,445
  • 3
  • 31
  • 44
4

First check if you have connection, ping directly to ip 91.189.92.201 that archive.ubuntu.com is pointed to:

ping 91.189.92.201

If you still can't reach the host it's not a dns problem.

Also if you have internet connection, you can make a hack. Just put a row into /etc/hosts file and problem solved:

91.189.92.201 archive.ubuntu.com

Justas Pukys
  • 124
  • 1
  • 1
  • 8
  • 1
    I can ping to `archive.ubuntu.com` but still it shows me the error `W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/trusty/InRelease` – Tinkaal Gogoi Nov 15 '16 at 16:33
3

I am using the version of Mint and after installing Docker and try to create an image of Ubuntu to do the apt-get update command does not recognize, to remedy the problem, I did step down

docker run -it -p 8080:80  ubuntu /bin/bash
echo "91.189.92.201 archive.ubuntu.com" >> /etc/hosts
cat /etc/hosts
apt-get update
  • Hi Kor; your code might be correct, but with some context it would make a better answer; for example, you could explain how and why this proposed change would resolve the questioner's problem, perhaps including a link to the relevant documentation. That would make it more useful to them, and also more useful to other site readers who are looking for solutions to similar problems. – Vince Bowdren Nov 02 '16 at 17:08
  • See if improved now! – cristofersousa Nov 04 '16 at 11:19
  • 1
    Interesting answer but the IP address changed since this was written so one might want to do a DNS lookup to retrieve the most up to date IP address for archive.ubuntu.com before doing this. – Emmanuel May 10 '20 at 22:20
2

I encounter the issue in two different case and the resolution was different...

First one with Win7 + virtualbox(Xubuntu 16.04) This comment did the job:https://stackoverflow.com/a/29659783/2260796

I modify the file /etc/default/docker:

DOCKER-OPTS="--ip-masq=true --dns my_ip_dns_win --dns 8.8.8.8 --dns 8.8.4.4" And run sudo service docker restart

Second one on a Xubuntu OS (ubuntu 16.04) The precedent resolution was not enough. This comment did the job: https://github.com/docker/docker/issues/1809 I had to comment one line in file /etc/NetworkManager/NetworkManager.conf:

dns=dnsmasq

Then run

sudo restart network-manager

Community
  • 1
  • 1
Garag
  • 101
  • 1
  • 1
  • 6
  • 1
    +1 for the `--ip-masq=true`. Very useful if you are behind another firewall and only the Docker host is allowed to talk to the outside world. – mofoe Jan 13 '18 at 22:54
1

Error with docker-compose I faced the same problem with docker-compose. I solve that by adding ENV http_proxy 'proxy.com' entry into Dockerfile.

Lasith Niroshan
  • 925
  • 10
  • 18
  • worked for me thanks. But consider that you should put 'ENV http_proxy 'proxy.com' ' in the same line and 'apt-get update' so both run in the same container. – vahidzolf Oct 05 '20 at 22:48
1

I was using Jenkins base image and no matter what I do, apt-get update was always failing. Eventually, this helped, removing /var/lib/apt/lists/ and /etc/apt/sources.list.d/* * did the trick.

USER root
RUN rm -rf /var/lib/apt/lists/*
RUN rm -rf /etc/apt/sources.list.d/*
RUN apt-get update
....Continue using apt-get for installing your stuff..
RUN apt-get install -y maven
Abhishek Galoda
  • 2,753
  • 24
  • 38
1

If you're running docker build you cannot specify --net=host This case happens.

In this case do:

  1. vim /etc/docker/daemon.json will be created if doesn't exist. Usually not.
  2. Add following content into file
{
    "dns": ["10.1.2.3", "8.8.8.8"]
}
  1. Restart docker sudo service docker restart if you don't want to use systemctl

I was using WSL2 Ubuntu. This worked.

jdk
  • 451
  • 1
  • 6
  • 18
0

Just use 'ubuntu:20.04' image (previous LTS) instead of 'ubuntu'. It works for me.