Dockerビルド時にnpm installが失敗する問題の原因と解決策

DockerでNode.jsアプリのイメージビルド中にnpm installEAI_AGAINエラーになる場合の問題点・原因・対応策です。

問題点:Dockerビルド中のnpm installがDNSエラーで失敗する

Dockerfile内でRUN npm installを実行すると、以下のようなエラーが発生してビルドが止まるケースがあります。

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

一方で、ビルド時にnpm installをスキップし、できあがったイメージから起動したコンテナ内で手動実行すると問題なく成功します。
これは一見するとネットワークが通っているように見えますが、ビルド時の環境に特有の問題が潜んでいます。

原因:ビルド時のコンテナネットワーク設定とDNS解決の違い

Dockerイメージのビルド中は、一時的に生成される中間コンテナ上でRUNコマンドが実行されます。
この中間コンテナは、起動後のコンテナとは異なるネットワーク設定を持つため、DNS名前解決に失敗することがあります。
具体的には、ビルド時の中間コンテナはDockerデーモンのデフォルトDNS設定を使いますが、環境によってはDNSキャッシュの不整合や名前解決のタイムアウトが発生し、EAI_AGAINのような一時的エラーを引き起こします。
つまり、ビルド時のネットワーク環境と起動後のネットワーク環境でDNSの挙動が異なることが根本原因です。

対応策:docker-composeでbuild時にnetwork: hostを指定してDNS問題を回避する

この問題を解決する方法は、ビルド時のネットワーク設定をホストのネットワークに切り替えることです。
具体的には、docker-compose.ymlbuildセクションに以下のようにnetwork: hostを追記します。

services:
  app:
    build:
      context: .
      network: host

これにより、ビルド時の中間コンテナがホストのネットワーク設定を共有し、DNS名前解決の失敗を回避します。

補足:その他のDNSトラブル対策

  • DockerデーモンのDNS設定を見直す
    /etc/docker/daemon.jsonにGoogle DNS(8.8.8.8など)を指定し、Dockerを再起動する方法を試す
  • ビルドと起動を分けて管理する
    docker build --network=hostで事前にビルドしてからdocker-compose upで起動する
  • ビルド時のnpm installを起動後に移行する
    ビルド時の環境依存を避けるため、コンテナ起動後にnpm installを実行する

まとめ

Dockerビルド時にnpm installがDNSエラーで失敗するのは、中間コンテナのネットワーク設定が起動後のコンテナと異なることが主な原因です。
docker-compose.ymlbuild.network: hostを指定することで、ホストのネットワークを利用してDNS問題を回避できます。

このエントリーをはてなブックマークに追加
にほんブログ村 IT技術ブログへ

コメント

メールアドレスが公開されることはありません。 が付いている欄は必須項目です