みずりゅの自由帳

主に参加したイベントやソフトウェア技術/開発について記録しています

ホストマシンの違いでコンテナ内でmix local.hexが実行できなかった話

よくある「Proxy環境下」でハマった話。

ElixirのPhoenix Frameworkの開発環境を作ろうと思い、Dockerfileを用意。
だが、同じDockerfileを使ってイメージ/コンテナを作成したにも関わらず、ホストマシンのOSの違いで「mix local.hex」コマンドが実行できる/できないが発生した。
どちらのDockerコンテナ内からも、curlwget、aptの実行は可能だった。

利用したホストマシンと実行結果は以下の通り。

  • CentOS 7.6 : mix local.hex が成功
  • Ubuntu 19.04 : mix local.hex が失敗

失敗時のエラー内容は、以下の通り。
コンテナ内で設定しているProxyを経由して外に出ようとしているが、何かしらの要因で外に出られない様子。

# mix local.hex
** (Mix) httpc request failed with: {:failed_connect, [{:to_address, {'proxy.local.jp', 8080}}, {:inet, [:inet], :nxdomain}]}

Could not install Hex because Mix could not download metadata at https://repo.hex.pm/installs/hex-1.x.csv.

エラーメッセージ中の「 {'proxy.local.jp', 8080}」はProxyサーバとポートの組み合わせ。
環境変数http_proxyhttps_proxyを追加する前は「{'repo.hex.pm', 443}」だったので、メッセージの1行目はto_addressに到達できない、という意味合いのエラーメッセージと考えられる。

結論:

ホストマシンが「Ubuntu 19.04」側のコンテナで、「/etc/resolv.conf」を修正したことで、エラーが解消できた。


対処内容:

ホストマシンが「Ubuntu 19.04」側のコンテナの「/etc/resolv.conf」に記述されていた、二つの設定を無効(コメント化)にした。

  • nameserver 8.8.8.8
  • nameserver 8.8.4.4

正確には、「nameserver 8.8.8.8」の無効化だけでも成功した。
ただし、「nameserver 8.8.4.4」も無効にする方が処理時間が短くなったので、こちらも無効化した。
なお、ホストマシン側の「Ubuntu 19.04」の「/etc/resolv.conf」には記載がない設定なので、コンテナ化する際に自動で付与されている可能性が考えられる。

詳細:

通信部分が怪しいと思い両ホストマシンの「/etc/resolv.conf」を比較してみると、「Ubuntu 19.04」側のコンテナにのみ「nameserver 8.8.8.8」「nameserver 8.8.4.4」が記載されていた。この二つの設定が悪さしていると想定し、コメント化して「mix local.hex」を実行してみると無事に実行された。

root@99edcc866a0f:/app# cat /etc/resolv.conf 
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 192.168.26.2
search localdomain
root@99edcc866a0f:/app# 
root@99edcc866a0f:/app# mix local.hex
** (Mix) httpc request failed with: {:failed_connect, [{:to_address, {'proxy.local.jp', 8080}}, {:inet, [:inet], :nxdomain}]}

Could not install Hex because Mix could not download metadata at https://repo.hex.pm/installs/hex-1.x.csv.

root@99edcc866a0f:/app# 
root@99edcc866a0f:/app# vim /etc/resolv.conf
root@99edcc866a0f:/app# 
root@99edcc866a0f:/app# cat /etc/resolv.conf 
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients directly to
# all known uplink DNS servers. This file lists all configured search domains.
#
# Third party programs must not access this file directly, but only through the
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

#nameserver 8.8.8.8
#nameserver 8.8.4.4
nameserver 192.168.26.2
search localdomain
root@99edcc866a0f:/app# 
root@99edcc866a0f:/app# mix local.hex
Are you sure you want to install "https://repo.hex.pm/installs/1.8.0/hex-0.20.1.ez"? [Yn] Y
* creating /root/.mix/archives/hex-0.20.1
root@99edcc866a0f:/app# 

念の為、Phoenix Frameworkがインストールできるかも確認。問題なく実行できた。

root@99edcc866a0f:/app# mix archive.install hex phx_new 1.4.3
Resolving Hex dependencies...
Dependency resolution completed:
New:
  phx_new 1.4.3
* Getting phx_new (Hex package)
All dependencies are up to date
Compiling 10 files (.ex)
Generated phx_new app
Generated archive "phx_new-1.4.3.ez" with MIX_ENV=prod
Are you sure you want to install "phx_new-1.4.3.ez"? [Yn] Y
* creating /root/.mix/archives/phx_new-1.4.3
root@99edcc866a0f:/app# 

補足:

エラーメッセージ「(Mix) httpc request failed with: {:failed_connect, [{:to_address」あたりでググると、Hexインストール用のファイル(hex-0.20.1.ezなど)やPhoenixのインストール用ファイル(phx_new-1.4.3.ezなど)をローカルにダウンロードした後で「mix archive.install」をするように書かれている情報が多く出てきた。
しかし、同じDockerfileを使っての違いが出たので、何かしら差異があるのではと思い調べた内容。

なお、「nameserver 8.8.8.8」「nameserver 8.8.4.4」はGoogle Public DNSに該当します。
名前の通りPublicなDNSのため、LAN内でのみ名前が設定されているProxyサーバは見つけられず、ということだと考えている。
Proxyを設定していない場合には、そもそもProxyサーバを経由していないので外(今回の場合、「repo.hex.pm」)に出れないという状況になったのかと。
Proxy環境下という状況下で、自分の環境下でだけたまたま発生した事象かもしれないが、同じような状況下の人が居るかもしれないので記録しておく。


また、今回のコンテナ作成に利用したDockerfileは、Elixir公式の「elixir:1.8.1」を利用して作成した。
「elixir:1.8.1」でのOSは「Debain 9」であり、DebianLinuxでの「/etc/resolv.conf」への対処はあくまで暫定に過ぎず、再起動などを行うと変更した設定は復活する。
ただし、hexコマンド以外のcurlやapt-getは問題なく行えていたので、Phoenix環境構築時に問題がなければ一旦は良しとした。
今後、Dockerコンテナ上でPhoenixを動かしてた際に問題が出たら、また調査していく予定。