Skip to content

chore(build): make Docker npm ci resilient to transient registry network errors#4303

Open
TaprootFreak wants to merge 1 commit into
developfrom
chore/npm-ci-network-resilience
Open

chore(build): make Docker npm ci resilient to transient registry network errors#4303
TaprootFreak wants to merge 1 commit into
developfrom
chore/npm-ci-network-resilience

Conversation

@TaprootFreak

@TaprootFreak TaprootFreak commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Problem

A DEV-deploy build recently failed on a single npm error code ECONNRESET during RUN npm ci in the Docker builder stage. A single transient npm-registry network blip should not fail an entire build/deploy.

The root cause is a fragility bug, not a one-off: the builder stage runs npm ci with npm defaults (fetch-retries=2, short timeouts) and there is no repo-level .npmrc, so one ECONNRESET / ETIMEDOUT aborts the whole build.

Fix (minimal, single source of truth)

  1. Add a repo-root .npmrc with network-resilience settings only (no registry override, no auth/tokens):

    fetch-retries=5
    fetch-retry-mintimeout=20000
    fetch-retry-maxtimeout=120000
    fetch-timeout=300000
    

    npm retries registry requests on transient network errors (incl. ECONNRESET / ETIMEDOUT); 5 retries with 20s→120s exponential backoff and a 5-min per-request timeout let npm ci survive a blip.

  2. Dockerfile: ADD --chown=node:node .npmrc . on the line before RUN npm ci, so the builder stage actually reads the config (previously only package.json + package-lock.json were ADDed before npm ci).

package.json / package-lock.json are untouched. Because the .npmrc sits at the repo root, it also transparently hardens the CI Build-and-test job (npm ci runs in the checkout) and local dev — one source of truth.

Verification (docker build on arm64)

  • docker build --target builder -t dfx-api-npmrc-test . → builder stage completes npm ci successfully with the .npmrc present; image builds clean.
  • docker run --rm dfx-api-npmrc-test npm config get fetch-retries5 (also fetch-retry-maxtimeout120000, fetch-timeout300000), proving the .npmrc is in effect during npm ci.
  • Throwaway image removed afterwards.

…ork errors

A single npm-registry ECONNRESET during `RUN npm ci` aborted a DEV-deploy build. npm defaults are weak (fetch-retries=2, short timeouts), so one transient blip fails the whole build/deploy.

Add a repo-root .npmrc with network-resilience settings only (no registry/auth) and ADD it before npm ci in the builder stage so the config is in effect. Also hardens the CI build+test job and local dev via a single source of truth.
@TaprootFreak

Copy link
Copy Markdown
Collaborator Author

Root-cause fix for the transient npm ci ECONNRESET that failed the DEV-deploy build on the release PR. A single registry blip should never fail a build/deploy; npm's defaults (2 retries, short timeouts) are too weak. Adds a minimal repo .npmrc (fetch-retries=5, 20s→120s backoff, 5-min per-request timeout — no registry/auth entries) and ADDs it in the Dockerfile before RUN npm ci so the builder stage reads it. Verified by an actual arm64 docker build --target builder: builds clean and npm config get fetch-retries → 5 in the build context. The repo .npmrc also hardens the 'Build and test' CI job's npm ci and local dev — single source of truth. CI green. Ready for review/merge.

@TaprootFreak
TaprootFreak marked this pull request as ready for review July 21, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant