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. 1.DNS resolution failure: Container can't resolve domain names
  2. 2.Network configuration: Bridge network not properly configured
  3. 3.Firewall rules: iptables or firewall blocking container traffic
  4. 4.IP forwarding disabled: Linux kernel not forwarding packets
  5. 5.MTU mismatch: Maximum transmission unit too large for network
  6. 6.Proxy configuration: Container needs proxy but not configured
  7. 7.Host networking issues: Host itself can't reach internet
  8. 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:

bash
# 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-image

In 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

ini
[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"
bash
sudo systemctl daemon-reload
sudo systemctl restart docker

Step 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 ```

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.