首頁

目前文章總數:210 篇

  

最後更新:2025年 12月 13日

0022. Docker build npm install 失敗 EAI_AGAIN 解析錯誤的原因與解法

日期:2026年 01月 10日

標籤: Jenkins Continuous Integration(CI) Ubuntu Linux Docker Docker-Compose Container

摘要:Jenkins


應用所需:已安裝 Docker-Compose
解決問題:Jenkins 部署前端專案時 DockerFile 使用 Npm install 時出現 npm ERR! code EAI_AGAIN 的解決方法
基本介紹:本篇分為 4 大部分。
第一部分:實務問題說明
第二部分:錯誤的真正意義
第三部分:解決方案
第四部分:參考文獻






第一部分:實務問題說明

Step 1:突然發生此問題

在 11/21 日,我們正在使用 CICD 執行 Jenkins Deploy,突然開始報錯,關鍵錯誤在以下 4 行

npm error code EAI_AGAIN
npm error syscall getaddrinfo
npm error errno EAI_AGAIN
npm error request to https://registry.npmjs.org/pnpm failed, reason: getaddrinfo EAI_AGAIN registry.npmjs.org




Step 2:換個環境驗證

我們環境很久沒有異動過腳本,因此我們將 Docker Image 換個公司內部機器 Pull 後重新執行 Docker Build
仍是出現相同的錯誤




第二部分:錯誤的真正意義

Step 1:定位出原因

1. 我們看到此錯誤訊息,確認是 DNS 查詢失敗,Docker 容器內無法解析 registry.npmjs.org 的域名。

91mnpm error code EAI_AGAIN



2. 觀察到指定的某個伺服器異常,因此用另一台相同網路環境的機器也報相同錯誤,因此定位出 上游伺服器異常

error request to https://registry.npmjs.org/pnpm failed



Step 2:檢查官方套件倉庫伺服器

registry.npmjs.org 是 npm 的官方套件倉庫,我們可以前往主要介面檢查 NPM 官方狀態頁面
比對 NPM 紀錄的重大故障時間只有 11/18 (三) 全球性的 CloudFlare 的 5hrs 35min 重大停機事件
而我們出錯的時間是 11/21(五) ,因此可以確定只是 暫時性上游伺服器異常,而非持續性的故障


Step 3:上游伺服器暫時性的定義

只有重大、全球性的災難故障,才會記錄於 NPM 官方狀態頁面 ,以下是不一定記錄的故障列表:

1. 區域性網路問題
2. 短暫抖動(< 5 分鐘)
3. 部分 CDN 節點異常
4. DNS 解析間歇性失敗
5. 特定地區或 ISP 的連線問題


總的來說,此問題為特定區域、短暫,都 非全球性 的問題,那麼就不會記錄於 NPM 官方狀態頁面



第三部分:解決方案

Step 1:短暫性處理方案 - Docker DNS 更換分析

我們確定只是區域性的異常,沒有記錄於 NPM 官方頁面上,因此可選擇臨時性的解決方案:

設定 Google 公共 DNS 8.8.8.8


當前用的是 Docker Container 因此要從 /etc/docker/daemon.json 進行配置

此作法的優缺點如下:

優點 缺點
高可用性,Google DNS 穩定度極高 (99.99%+) 無法解析內部私有域名 (這是最大問題!)
全球 Anycast 網路,回應速度快 繞過公司 DNS,可能違反安全政策
不受公司內部 DNS 故障影響 失去內部 DNS 的功能 (如內部服務發現)
避免 DNS 快取污染問題 如果有私有 npm registry,會無法存取
適合存取公開套件來源 DNS 查詢會暴露給 Google (隱私考量)


因為我們的目標是:臨時緊急修復,快速恢復服務 適合我們的環境,因此可以採用
實務上需要以自己的公司內部的專案、環境架構再做取捨(依照上述的優缺點評估)

Step 2:Docker DNS 更換 - 找出 DNS 實際位址

Docker 會讀取宿主機的 /etc/resolv.conf 檔案,將裡面的 nameserver 複製到容器內的 /etc/resolv.conf
然後容器使用這些 DNS 伺服器來解析域名,因此預設沒有設定 Docerk 的 daemon.json ,容器就會繼承宿主機 DNS 設定

輸入以下指令檢查,得出本地查詢 DNS 會轉送到 nameserver 127.0.0.53 還需要找出監聽這個位址的服務

cat /etc/resolv.conf




Step 3:Docker DNS 更換 - 確定實際位址

監聽此服務的真正位置是在 192.168.99.188 ,這是我們主要的 DNS 伺服器位置
因此 Docker 的 daemon.json 未設定時,會自動導向到 192.168.99.188 DNS Server

resolvectl status


最終我們可以 先採用 8.8.8.8 繞過問題 ,過一段時間後,在移除此設定,交由統一的 DNS 伺服器管理


Step 4:更換 Docker DNS

進入 Ubuntu Jenkins 主機 (Docker Build Image 的機器,因為這時才會 NPM 下載),到以下路徑開啟此檔案:

/etc/docker/daemon.json 



添加以下:

"dns" : [ "8.8.8.8" ]




Step 5:重啟 Docker

設定完成,必須重啟 Docker

sudo systemctl restart docker



Step 6:驗證已解決 & 結論

最後建置相同的 Image 在 Jenkins Server 上,如下圖,可以觀察到已恢復正常

結論 : 因為我們知道這是 暫時性 上游伺服器的異常,因此先更換 DNS 到 Google,後續仍需移除讓公司的 DNS 伺服器管理





第四部分:參考文獻

Step 1:參考相關問題 - StackOverFlow

Stack OverFlow 的此篇,也有遇到相同問題
npm ERR! request to https://registry.npmjs.org during Dockerizing a Node.js web app
我們參考下方的回覆,延伸參考 :

if someday any have this problem you can resolve with this docker build . 
--network host -t mytag .. or another suggestion suggestion 
you can check the following link https://github.com/StefanScherer/dockerfiles-windows/issues/270



Step 2:參考相關問題 - Docker 已知異常

以下是引用內文:

Simple fix is to create the file /etc/docker/daemon.json


這是普遍遇到此問題的常態性解法