When I upgraded from Docker 1.4 to 1.5 using the lxc_docker
package, I encountered this puzzling scenario:
$ docker version
Client version: 1.5.0
Client API version: 1.17
FATA[0000] Error response from daemon: 404 page not found
Yet the old client worked perfectly:
$ /usr/bin/docker-old version
Server version: 1.5.0
Server API version: 1.17
The root cause lies in how Docker 1.5 handles local socket communication when proxy environment variables (HTTP_PROXY
, HTTPS_PROXY
) are present. The newer version attempts to route UNIX socket communication through the proxy, which obviously fails.
While setting NO_PROXY
works:
export NO_PROXY="/var/run/docker.sock"
More robust solutions include:
# Option 1: System-wide docker configuration
echo 'export NO_PROXY="/var/run/docker.sock,$NO_PROXY"' >> /etc/profile.d/docker_proxy.sh
# Option 2: Docker systemd unit override
mkdir -p /etc/systemd/system/docker.service.d
cat << EOF > /etc/systemd/system/docker.service.d/proxy.conf
[Service]
Environment="NO_PROXY=/var/run/docker.sock"
EOF
systemctl daemon-reload
systemctl restart docker
To inspect the actual API call flow:
strace -f -e trace=network docker version 2>&1 | grep connect
For developers creating Docker clients, always handle these cases:
func getDockerClient() (*client.Client, error) {
if os.Getenv("HTTP_PROXY") != "" {
if _, err := os.Stat("/var/run/docker.sock"); err == nil {
return client.NewClientWithOpts(
client.WithHost("unix:///var/run/docker.sock"),
client.WithHTTPClient(&http.Client{
Transport: &http.Transport{
Proxy: nil, // Explicitly disable proxy for UNIX sockets
},
}),
)
}
}
return client.NewClientWithOpts(client.FromEnv)
}
When upgrading from Docker 1.4 to 1.5, many users encounter this puzzling behavior:
$ docker ps
FATA[0000] Error response from daemon: 404 page not found
Yet oddly, the old client binary works perfectly:
$ /usr/bin/docker-old images
REPOSITORY TAG IMAGE ID CREATED
The core issue stems from how Docker 1.5+ handles API routing through Unix sockets when HTTP_PROXY is set:
- New versions attempt to route
unix:///var/run/docker.sock
through HTTP proxies - The proxy tries to handle Unix socket connections as HTTP requests
- Daemon receives malformed requests, returning 404 errors
Method 1: NO_PROXY Configuration
The cleanest approach is modifying your environment variables:
# Add to ~/.bashrc or systemd service file
export NO_PROXY="localhost,127.0.0.1,/var/run/docker.sock"
Method 2: Daemon Configuration
For systemd deployments, create an override file:
# /etc/systemd/system/docker.service.d/override.conf
[Service]
Environment="NO_PROXY=/var/run/docker.sock"
Method 3: Client Flag (Temporary)
For quick testing, use the direct socket flag:
docker -H unix:///var/run/docker.sock version
This behavior affects:
- Docker 1.5.0 through 1.12.x
- Occurs with both HTTP_PROXY and HTTPS_PROXY
- More prevalent in corporate environments with strict proxy rules
Confirm your fix worked with:
env | grep -i proxy
curl --unix-socket /var/run/docker.sock http://localhost/version