What's Actually Happening
Your Docker container is running but cannot access the internet. Applications inside the container fail to connect to external services, package managers can't download packages, and DNS resolution fails. This is a networking issue where the container can't reach external networks.
The Error You'll See
```bash $ docker exec container-name ping google.com ping: bad address 'google.com'
$ docker exec container-name curl https://google.com curl: (6) Could not resolve host: google.com
$ docker exec container-name apt-get update Err:1 http://deb.debian.org/debian bullseye InRelease Temporary failure resolving 'deb.debian.org'
$ docker exec container-name npm install npm ERR! network request to https://registry.npmjs.org failed, reason: getaddrinfo ENOTFOUND registry.npmjs.org
$ docker exec container-name wget google.com --2024-01-01 12:00:00-- http://google.com/ Resolving google.com (google.com)... failed: Name or service not known. ```
Why This Happens
- 1.DNS resolution failure: Container can't resolve domain names
- 2.Network configuration: Bridge network not properly configured
- 3.Firewall rules: iptables or firewall blocking container traffic
- 4.IP forwarding disabled: Linux kernel not forwarding packets
- 5.MTU mismatch: Maximum transmission unit too large for network
- 6.Proxy configuration: Container needs proxy but not configured
- 7.Host networking issues: Host itself can't reach internet
- 8.Docker daemon issues: Docker networking stack corrupted
Step 1: Verify the Problem
Test connectivity from inside and outside the container:
```bash # Test host connectivity first ping -c 4 google.com curl -I https://google.com
# Test container connectivity docker exec container-name ping -c 4 google.com docker exec container-name curl -I https://google.com
# Test DNS resolution in container docker exec container-name nslookup google.com docker exec container-name cat /etc/resolv.conf
# Test IP connectivity (bypass DNS) docker exec container-name ping -c 4 8.8.8.8
# Test specific ports docker exec container-name nc -zv google.com 80 docker exec container-name nc -zv google.com 443 ```
Step 2: Check and Fix DNS Configuration
DNS is often the culprit:
```bash # Check container DNS settings docker exec container-name cat /etc/resolv.conf
# Check Docker daemon DNS config cat /etc/docker/daemon.json
# Configure DNS in daemon.json sudo nano /etc/docker/daemon.json ```
Add or update DNS configuration:
``json
{
"dns": ["8.8.8.8", "8.8.4.4", "1.1.1.1"],
"dns-search": ["example.com"]
}
```bash # Restart Docker sudo systemctl restart docker
# Or configure DNS per container docker run --dns 8.8.8.8 --dns 8.8.4.4 my-image
# In docker-compose.yml version: '3.8' services: app: image: my-image dns: - 8.8.8.8 - 8.8.4.4 ```
Use host DNS mode:
``bash
# Use host's DNS configuration
docker run --dns-search=. --dns=127.0.0.1 my-image
Step 3: Enable IP Forwarding
Container networking requires IP forwarding:
```bash # Check if IP forwarding is enabled cat /proc/sys/net/ipv4/ip_forward # Should return 1
# If disabled, enable temporarily sudo sysctl -w net.ipv4.ip_forward=1
# Enable permanently sudo nano /etc/sysctl.conf ```
Add or uncomment:
``ini
net.ipv4.ip_forward=1
```bash # Apply changes sudo sysctl -p
# Verify cat /proc/sys/net/ipv4/ip_forward ```
Step 4: Fix iptables and Firewall
Docker needs iptables rules for NAT:
```bash # Check iptables rules sudo iptables -L -n -v sudo iptables -t nat -L -n -v
# Check Docker-specific rules sudo iptables -L DOCKER -n -v sudo iptables -t nat -L DOCKER -n -v
# Restore Docker iptables rules # Stop Docker sudo systemctl stop docker
# Flush iptables (caution: removes all rules) sudo iptables -F sudo iptables -t nat -F sudo iptables -t mangle -F sudo iptables -X
# Restart Docker to recreate rules sudo systemctl start docker
# If using firewalld sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0 sudo firewall-cmd --reload
# If using ufw sudo ufw allow in on docker0 sudo ufw reload ```
For firewalld issues: ```bash # Check firewalld status sudo firewall-cmd --state
# Add Docker interface to trusted zone sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
# Enable masquerading sudo firewall-cmd --permanent --zone=public --add-masquerade
# Reload sudo firewall-cmd --reload
# Restart Docker sudo systemctl restart docker ```
Step 5: Fix Network Bridge Issues
Reset Docker bridge networking:
```bash # Stop Docker sudo systemctl stop docker
# Check docker0 interface ip addr show docker0
# Remove and recreate docker0 sudo ip link delete docker0
# Start Docker to recreate bridge sudo systemctl start docker
# Verify docker0 exists ip addr show docker0
# Check bridge details brctl show docker0 ```
Configure custom bridge network: ```bash # Create custom bridge with specific settings docker network create \ --driver bridge \ --subnet=172.25.0.0/16 \ --gateway=172.25.0.1 \ my-bridge
# Run container on custom bridge docker run --network my-bridge my-image ```
Step 6: Configure Proxy for Container
If behind a corporate proxy:
# Run with proxy environment variables
docker run \
-e HTTP_PROXY=http://proxy.company.com:8080 \
-e HTTPS_PROXY=http://proxy.company.com:8080 \
-e NO_PROXY=localhost,127.0.0.1,.company.com \
my-imageIn docker-compose.yml:
``yaml
version: '3.8'
services:
app:
image: my-image
environment:
- HTTP_PROXY=http://proxy.company.com:8080
- HTTPS_PROXY=http://proxy.company.com:8080
- NO_PROXY=localhost,127.0.0.1,.company.com
Configure Docker daemon for proxy:
``bash
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.company.com:8080"
Environment="HTTPS_PROXY=http://proxy.company.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,.company.com"sudo systemctl daemon-reload
sudo systemctl restart dockerStep 7: Fix MTU Issues
Large packets may be dropped if MTU is too large:
```bash # Check host MTU ip link show | grep mtu
# Check container MTU docker exec container-name ip link show | grep mtu
# Configure Docker MTU in daemon.json sudo nano /etc/docker/daemon.json ```
{
"mtu": 1400
}```bash sudo systemctl restart docker
# Or configure per network docker network create --opt com.docker.network.driver.mtu=1400 my-network ```
Step 8: Use Host Network Mode
As a workaround, use host networking:
```bash # Run with host network (shares host's network stack) docker run --network host my-image
# In docker-compose.yml version: '3.8' services: app: image: my-image network_mode: host ```
Note: Host network mode has security implications and port mapping is ignored.
Step 9: Restart Networking Stack
Complete network reset:
```bash # Stop all containers docker stop $(docker ps -aq)
# Stop Docker sudo systemctl stop docker
# Stop docker socket sudo systemctl stop docker.socket
# Remove network interfaces sudo ip link delete docker0
# Flush iptables sudo iptables -F sudo iptables -t nat -F sudo iptables -t mangle -F sudo iptables -X sudo iptables -t filter -F sudo iptables -t nat -F
# Restart Docker sudo systemctl start docker
# Test docker run --rm alpine ping -c 4 google.com ```
Step 10: Debug Network Inside Container
Diagnose from inside container:
```bash # Run a debug container docker run --rm -it alpine sh
# Inside container, test: ping -c 4 8.8.8.8 # Test IP connectivity ping -c 4 google.com # Test DNS resolution nslookup google.com # DNS lookup cat /etc/resolv.conf # Check DNS config ip route # Check routing table ip addr # Check network interfaces
# Trace network path traceroute google.com
# Check if ports are open nc -zv google.com 80 nc -zv google.com 443 ```
Verify the Fix
Confirm container has internet access:
```bash # Test DNS resolution docker run --rm alpine nslookup google.com
# Test HTTP connectivity docker run --rm alpine wget -q -O- https://google.com > /dev/null && echo "OK"
# Test package installation (apt) docker run --rm debian apt-get update && echo "OK"
# Test package installation (apk) docker run --rm alpine apk update && echo "OK"
# Test npm docker run --rm node npm ping
# Full connectivity test docker run --rm alpine sh -c "ping -c 4 google.com && wget -q -O- https://google.com" ```
Your container should now have full internet connectivity.