How to Fix Docker Compose Build Failing on npm install Due to Network Timeout
Quick answer
Running docker compose build fails during the npm install step with a network timeout, even though your host machine's internet connection is clearly working...
Running docker compose build fails during the npm install step with a network timeout, even though your host machine's internet connection is clearly working fine outside the container. This points at a networking issue specific to the Docker build environment itself, not your actual internet connectivity.
The Problem
The build proceeds normally until it reaches the dependency installation step, then hangs and eventually fails:
$ docker compose build
[+] Building 245.2s (8/12)
=> [app 4/7] RUN npm install
------
> [app 4/7] RUN npm install:
npm error code ETIMEDOUT
npm error syscall connect
npm error errno ETIMEDOUT
npm error network request to https://registry.npmjs.org/react failed, reason: connect ETIMEDOUT
Meanwhile, npm install run directly on the host machine (outside Docker entirely) works without any issue at all.
Why It Happens
Docker containers have their own network stack, which can behave differently from your host machine's networking in ways that specifically affect long-lived external connections like package registry downloads. Common causes:
- Docker's default DNS resolution inside the build container isn't correctly configured, especially on certain corporate networks or VPNs where the host's DNS works fine but Docker's internal DNS forwarding doesn't inherit the same configuration.
- MTU (Maximum Transmission Unit) mismatches between the Docker virtual network and the actual physical network, particularly common over VPN connections, causing certain packet sizes to silently fail or fragment incorrectly.
- npm's default timeout is too short for a genuinely slow (but not entirely broken) connection, especially when installing a large dependency tree from within a resource-constrained build environment.
- A corporate proxy or firewall isn't being passed through to the Docker build process, since build-time network requests don't automatically inherit host-level proxy environment variables unless explicitly configured.
- Registry-side rate limiting or transient outages, less common but worth ruling out if the issue is intermittent rather than fully consistent.
The Fix
First, increase npm's own timeout and retry settings, since a slower-but-working connection inside the container is a common and easy-to-fix contributor:
# Dockerfile
RUN npm config set fetch-timeout 60000 && \
npm config set fetch-retries 5 && \
npm install
If the issue is DNS-related, explicitly set a reliable DNS server for the Docker build, either globally in Docker's daemon configuration or per-build:
# /etc/docker/daemon.json
{
"dns": ["8.8.8.8", "1.1.1.1"]
}
Restart Docker after changing the daemon configuration:
sudo systemctl restart docker
For a Compose-specific override without touching the global daemon config:
# docker-compose.yml
services:
app:
build:
context: .
network: host # uses the host's network directly for the build, bypassing Docker's own networking
If MTU mismatch over a VPN is the suspected cause, explicitly set a smaller MTU for Docker's network, since VPN tunnels often need a smaller MTU than a standard physical network connection:
# /etc/docker/daemon.json
{
"mtu": 1400
}
If you're behind a corporate proxy, pass proxy environment variables explicitly into the build, since they don't propagate automatically:
docker compose build --build-arg HTTP_PROXY=http://proxy.company.com:8080 --build-arg HTTPS_PROXY=http://proxy.company.com:8080
And reference them inside the Dockerfile so npm actually picks them up during the install step:
# Dockerfile
ARG HTTP_PROXY
ARG HTTPS_PROXY
ENV HTTP_PROXY=$HTTP_PROXY
ENV HTTPS_PROXY=$HTTPS_PROXY
RUN npm install
Still Not Working?
If none of the network-level fixes resolve it, isolate whether the problem is genuinely network connectivity or something else disguising itself as a timeout, by testing basic connectivity from directly inside a running container using the same base image:
docker run --rm node:20 curl -v https://registry.npmjs.org
If this simple connectivity test also hangs or times out, the problem is confirmed to be in Docker's networking layer itself rather than anything npm-specific, and the fix belongs in Docker's daemon or network configuration as covered above. If the basic connectivity test succeeds but npm install specifically still fails, consider switching to a faster, more resilient package manager or registry mirror as a practical workaround while you continue investigating the underlying network issue:
RUN npm config set registry https://registry.npmmirror.com
RUN npm install