【Rails】gem updateやgem installコマンドでtimed outやCould not find a valid gemが出たときの対処法

rails-how-to-treat-gem-update-timed-out Rails
記事内に広告が含まれていることがあります。

Rubyのバージョンアップに伴い、Rialsをインストールする必要ができたので、gem updateやgem install コマンドを実行したところ、長時間待たされた挙句、次のようなエラーが発生。

$ gem update --system
ERROR:  While executing gem ... (Gem::RemoteFetcher::UnknownHostError)
    timed out (https://rubygems.org/specs.4.8.gz)
$ gem install bundler
ERROR:  Could not find a valid gem 'bundler' (>= 0), here is why:
          Unable to download data from https://rubygems.org/ - timed out (https://api.rubygems.org/specs.4.8.gz)

https://rubygems.org/specs.4.8.gz および、https://api.rubygems.org/specs.4.8.gzにアクセスしようとしたが、接続できずタイムアウトが発生している。

このエラーの原因と解決方法についてです。

エラーの原因

このエラーは、gemの最新情報を取得するために、https://api.rubygems.org/specs.4.8.gz にアクセスする必要がありますが、このURLにアクセスできなかったために発生しています。

エラーの要因は大きく2つあります。

  1. IPv6を利用している
  2. 会社のVPNなどプロキシサーバーを利用している

会社のVPNやIPv6アドレスで接続しようとすると接続できません。api.rubygems.orgの暫定的なエラーと思いますがとにかくできません。

(補足)接続状況の確認方法

どのIPアドレスで接続できていなくて、どのIPアドレスだと接続できるのかを確認します。

wgetコマンドを使います。wgetは接続に失敗した場合に、自動でリダイレクトをかけて接続できるホストを探してくれます。(再帰処理と言います)

$ wget URL

$ wget https://api.rubygems.org/specs.4.8.gz
--2021-07-07 16:57:51--  https://api.rubygems.org/specs.4.8.gz
api.rubygems.org (api.rubygems.org) をDNSに問いあわせています... 2a04:4e42:200::483, 2a04:4e42:400::483, 2a04:4e42:600::483, ...
api.rubygems.org (api.rubygems.org)|2a04:4e42:200::483|:443 に接続しています... 失敗しました: Operation timed out.
api.rubygems.org (api.rubygems.org)|2a04:4e42:400::483|:443 に接続しています... 失敗しました: Operation timed out.
api.rubygems.org (api.rubygems.org)|2a04:4e42:600::483|:443 に接続しています... 失敗しました: Operation timed out.
api.rubygems.org (api.rubygems.org)|2a04:4e42::483|:443 に接続しています... 失敗しました: Operation timed out.
api.rubygems.org (api.rubygems.org)|151.101.193.227|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 4431303 (4.2M) [application/octet-stream]
`specs.4.8.gz' に保存中

specs.4.8.gz     100%[==========>]   4.23M  11.7MB/s 時間 0.4s     

2021-07-07 17

実行結果を見ると、IPv6のアドレス(2a04:4e42:200::483など)は接続に失敗しています。

一方で、IPv4アドレス(151.101.193.227)は接続に成功しています。ちなみに後ろの443はSSL(https)で接続しているという意味です。

エラー対処法

IPv4で接続できることがわかったので、まずはrubygems.orgがどのIPアドレスを使っているかを確認します。

IPv4アドレスの確認

hostコマンドでドメイン名を指定すると、IPアドレスの一覧が表示されます。

$ host rubygems.org

$ host rubygems.org
rubygems.org has address 151.101.193.227
rubygems.org has address 151.101.1.227
rubygems.org has address 151.101.65.227
rubygems.org has address 151.101.129.227
rubygems.org has IPv6 address 2a04:4e42:600::483
rubygems.org has IPv6 address 2a04:4e42:400::483
rubygems.org has IPv6 address 2a04:4e42::483
rubygems.org has IPv6 address 2a04:4e42:200::483
rubygems.org mail is handled by 10 mxa.mailgun.org.
rubygems.org mail is handled by 10 mxb.mailgun.org.

サブドメインも同じIPアドレスになります

$ host api.rubygems.org
api.rubygems.org is an alias for rubygems.org.
rubygems.org has address 151.101.129.227
rubygems.org has address 151.101.65.227
rubygems.org has address 151.101.1.227
rubygems.org has address 151.101.193.227
rubygems.org has IPv6 address 2a04:4e42:600::483
rubygems.org has IPv6 address 2a04:4e42::483
rubygems.org has IPv6 address 2a04:4e42:200::483
rubygems.org has IPv6 address 2a04:4e42:400::483
rubygems.org mail is handled by 10 mxb.mailgun.org.
rubygems.org mail is handled by 10 mxa.mailgun.org.

ドメイン名とIPv4アドレスを紐付ける

MacなどUnix系OSには /etc/hosts というファイルがあります。この中で、「このドメイン名の場合はこのIPアドレスにつなげる」といった処理を記述することができます。

このファイルをvimエディタで開きます。読み込みのみのアクセス権限がかかっているので、sudoでスーパーユーザーとして開きます。

$sudo vim /etc/hosts

開いたら以下のように末尾に追記します。

# when the system is booting.  Do not change this entry.
##
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost
# Added by Docker Desktop
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal

##以下追記
#gem IPv4アドレス
151.101.193.227 rubygems.org
151.101.1.227   rubygems.org
151.101.65.227  rubygems.org
151.101.129.227 rubygems.org

IPv6で接続しようとすることでエラーが発生するので、指定のドメイン名でIPv4のIPアドレスに接続するように設定します。

/etc/hosts の書き方は 「<IPアドレス> <紐づけるドメイン名>」 とします。

上記の場合、「rubygems.org」のドメイン名でアクセスしようとしたら、IPアドレスは「151.101.193.227」「151.101.1.227」「151.65.1.227」「151.129.1.227」を叩くという処理になります。

以上で設定が完了です。

社内VPNを切る

会社のVPNにつかがっているとプロキシサーバーで弾かれてデータを取得できないことがあります。

もし、VPNに接続している場合は切断します。

コマンドの実行

コマンドを実行してみるとtimeoutすることなく無事処理を実行することができました。

$ gem install bundler
Fetching bundler-2.2.22.gem
Successfully installed bundler-2.2.22
Parsing documentation for bundler-2.2.22
Installing ri documentation for bundler-2.2.22
Done installing documentation for bundler after 4 seconds
1 gem installed


(補足)Docker上のRailsプロジェクトの場合

Docker上にあるプロジェクトの場合は、自分のPC(ローカル)でgemやRailsのコマンドを叩いても、Docker上のプログラムには反映されません。

そもそも、Docker上のプログラムを指していないので、本来は出ないはずのエラーが発生したりします。

その場合は、Railsが動いているDockerコンテナに入り、gemコマンドを実行します。

#起動中のdockerコンテナ一覧を確認
docker ps

#コンテナの中に入る
docker exec -it <コンテナ名> bash
root@cee9a2a0d27e:/app#
タイトルとURLをコピーしました