Keywords: Docker | DNS configuration | apt-get update failure
Abstract: This article delves into the root cause of apt-get update command failures in Docker containers, focusing on DNS configuration problems. By analyzing common errors such as 'Could not resolve' encountered by users, and referencing the best answer's solution, it explains in detail how to resolve network resolution issues by modifying Docker daemon DNS settings. Additional insights from other answers are included, covering multiple configuration methods like editing /etc/default/docker, daemon.json files, and handling differences in /etc/resolv.conf across Ubuntu versions. Code examples and step-by-step instructions are provided to help readers comprehensively understand and address similar issues.
Problem Background and Symptom Description
When using Docker containers, users often encounter failures when executing the apt-get update command. Typical error messages include Could not resolve 'archive.ubuntu.com' or network connection failures. For example, after running sudo docker run -i -t ubuntu:14.04 /bin/bash and attempting to update the package list, the system cannot resolve the Ubuntu repository domain names. Users may have checked the /etc/resolv.conf file inside the container, confirming correct DNS server configuration (e.g., using 8.8.8.8 and 8.8.4.4), but still cannot ping external hosts like google.com, with errors such as ping: unknown host. This indicates that the root cause is DNS resolution, not simple network connectivity.
Root Cause Analysis
The core issue is improper DNS configuration in Docker containers. Docker copies the host's /etc/resolv.conf into containers by default, but if the host configuration is incorrect or restricted by firewalls, containers will fail to resolve domain names. In corporate network environments, firewalls may block access to public DNS servers (e.g., Google's 8.8.8.8), causing network calls to fail inside containers. Additionally, different Ubuntu versions have varying mechanisms for generating /etc/resolv.conf (e.g., NetworkManager vs. systemd-resolved), which can introduce local DNS caches (e.g., 127.0.0.53) that do not work properly in containers.
Detailed Solutions
Based on the best answer, resolving this issue requires configuring the Docker daemon to use accessible DNS servers. Specific methods depend on the Docker installation type:
Ubuntu Package Installation
Edit the /etc/default/docker file to add DNS server options. For example:
DOCKER_OPTS="--dns 10.1.2.3 --dns 8.8.8.8"
Here, 10.1.2.3 should be replaced with an internal DNS server, and 8.8.8.8 as a backup. Multiple DNS servers can be added for redundancy. After modification, restart the Docker service to apply the configuration:
sudo service docker restart
Binary Installation
If Docker is installed via binaries, specify DNS servers when starting the daemon:
sudo docker -d -D --dns 10.1.2.3 --dns 8.8.8.8 &
This command starts the Docker daemon with DNS settings, and & runs it in the background.
Additional Configuration Methods
Referencing other answers, DNS configuration can also be adjusted as follows:
Using daemon.json File
Edit /etc/docker/daemon.json (create if it doesn't exist) to add DNS settings:
{
"dns": ["10.1.2.3", "8.8.8.8"]
}
Restart the Docker daemon: sudo systemctl restart docker. This method is suitable for modern Docker versions and takes precedence over /etc/default/docker.
Fixing Host /etc/resolv.conf
Since Docker copies the host configuration, ensuring its correctness is crucial. For different Ubuntu versions:
- Ubuntu 16.04 and earlier: Edit
/etc/NetworkManager/NetworkManager.conf, comment out thedns=dnsmasqline (add#), then restart NetworkManager:sudo systemctl restart network-manager. - Ubuntu 18.04 and later: By default, systemd-resolved is used, and
/etc/resolv.confmay point to a local cache (127.0.0.53). Change the symlink to use real DNS servers:sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf.
Verification and Testing
After configuration, start a new container and test DNS resolution:
sudo docker run -it ubuntu /bin/bash
cat /etc/resolv.conf # Verify DNS server configuration
ping google.com # Test network connectivity
apt-get update # Execute the update command
If everything is correct, apt-get update should execute successfully without errors. For quick testing, the --net=host option can be used to let the container share the host's network stack, but this is not recommended for production due to reduced container isolation.
Summary and Best Practices
Failures of apt-get update in Docker containers are often due to DNS configuration issues. Solutions include configuring the Docker daemon to use appropriate DNS servers and ensuring the host's /etc/resolv.conf is correct. It is recommended to prioritize using daemon.json for configuration, as it is more flexible and manageable. In corporate networks, internal DNS servers should be used to avoid firewall problems. Regularly checking container network settings can prevent similar issues. By understanding Docker networking mechanisms and DNS principles, users can operate containerized environments more effectively.