Docker Desktop から Rancher Desktop に変更したときのトラブルシューティング

環境
- MacBook Pro(2021, Apple M1 Pro)
- MacOS: 12.6.1
- Docker Desktop: 4.13.1
- Rancher Desktop: 1.6.2
※書いている途中で変わる(上がる)可能性があります
Dockerの構成
Railsアプリケーションの開発環境として使用しているものです。
必要な情報だけ記載しています。
version: "3"
volumes:
db-data:
backend-bundle:
backend-vendor:
backend-tmp:
services:
db:
image: postgres:14
volumes:
- db-data:/var/lib/postgresql/data
ports:
- "5432:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
backend:
ports:
- "8080:8080"
command: > # 残っているかもしれないプロセスを消してから立ち上げる
/bin/sh -c "rm -f tmp/pids/server.pid &&
bundle exec rails s -p 8080 -b '0.0.0.0'"
volumes:
# コンテナのグローバルにインストールされたgemを、Docker Volumeにキャッシュとして保存する
- backend-bundle:/usr/local/bundle
# アプリケーションのソースコードをコンテナにマウントする
- ./backend:/app
# 以下はパフォーマンスのためローカルをマウントしない
- backend-vendor:/app/vendor
depends_on:
- db
tty: true
stdin_open: true

まずは移行方法
前提としてDocker Desktopを使っているものとします。
- Docker Desktopを終了します(アンインストールしなくてOK)
- Rancher Desktopをインストール・開始
コンテキストの切り替え
Docker CLI が Docker Desktop or Rancher Desktop のコンテキストを切り替えることができます。Rancher Desktopをインストール直後は、コンテキストが rancher-desktop
になります。コンテキストの確認は docker info
でできます。
Docker Desktopに切り戻す場合
- Rancher Desktopを終了します
- Docker Desktopを開始します
docker context use desktop-linux
Rancher Desktopに切り替える場合
- Docker Desktopを終了します
- Rancher Desktopを開始します
docker context use rancher-desktop

Railsの再読み込みが効かない
Railsではdevelopment環境のデフォルトで、ファイルの変更を検知して再読込する機能があります。これによりRailsサーバーを再起動せずとも変更を反映することができます。Rancher Desktopにしたところ、これが効かなくなりました。
再読み込みの仕組み
デフォルトのRailsは、変更されたファイルをイベンテッドファイルモニタで検出しますが、自動読み込みパスを調べてファイル変更を検出することも可能です。これは、config.file_watcherの設定で制御されます。
https://railsguides.jp/autoloading_and_reloading_constants.html#再読み込み
config.file_watcher
を ActiveSupport::FileUpdateChecker
にすればいいという情報は見つかるのですが、 デフォルトのイベンテッドファイルモニタがなぜ効かないのか気になります。イベンテッドファイルモニタは、 gem listen
が行っているようです。
デフォルトのRailsではActiveSupport::FileUpdateChecker、およびActiveSupport::EventedFileUpdateChecker(これはlistenに依存します)が指定されます。
https://railsguides.jp/configuring.html#config-file-watcher
listenのissueを探してみると、inotify watches was used up
という情報が見つかりました。
inotify
についてRancher Desktopのissueを探してみると、どうやら初期値がすごく小さいという情報が見つかりました。
案内されたissueに初期値の変更手順が書いてあります。

まずは一時的に変更してみる
コンテナに接続して現状の値を確認
# cat /proc/sys/fs/inotify/max_user_watches
30515
変更してみる
# echo fs.inotify.max_user_watches=524288 | tee -a /etc/sysctl.conf
# sysctl -p
sysctl: permission denied on key "fs.inotify.max_user_watches"
このkeyはpermission deniedって言われてしまう。
コンテナを再起動してみてもダメ。
なるほど、ホスト側のVMと共有しているので、ホスト側を変えないとダメらしい
VMにsshするには、rdctl
を使えばいいらしい
ローカルにrdctl
が入っていない?
$ rdctl shell
zsh: command not found: rdctl
パスが通っていないだけでした。max_user_watches
の値がコンテナと同じであることが確認できた。
$ ~/.rd/bin/rdctl shell
# cat /proc/sys/fs/inotify/max_user_watches
30515
VMの中でmax_user_watches
を変えてみる。
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
fs.inotify.max_user_watches=524288
$ sudo sysctl -p
fs.inotify.max_user_watches = 524288
$ cat /proc/sys/fs/inotify/max_user_watches
524288
コンテナを再起動して、コンテナの中でも確認。
# cat /proc/sys/fs/inotify/max_user_watches
524288
やったね。
がしかし、再読み込みはまだ効かず🥲

Docker Desktopの方はどうなのか?
# cat /proc/sys/fs/inotify/max_user_watches
1048576
同じ数にしてみよう
$ echo fs.inotify.max_user_watches=1048576 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
やっぱり再読み込みは効かない。なにか別の問題があるのだろう。

ちなみに config.file_watcher = ActiveSupport::FileUpdateChecker
にすると、再読み込みは効きました。

ローカルに立ち上げたフロントエンドサーバーからコンテナにアクセスできない
最初は問題が起きていなかったが、最近になってできなくなってしまった。
環境
- MacOS: 12.6.1
- Rancher Desktop: 1.6.2
状況
- APIサーバーをコンテナで起動する。port: 8080。ブラウザやAPIクライアントからはアクセスできる。
- フロントエンドサーバーをローカルで起動する。port: 3000。APIサーバーにアクセスしようとすると
Error: connect ECONNREFUSED ::1:8080
となる。- 該当のURLに対してブラウザからアクセスすると成功する。
- APIサーバーをDocker Desktopで起動するとフロントエンドサーバーからのアクセスに成功する。

フロントエンドサーバーからのAPIサーバーの宛先ホストを localhost
から 127.0.0.1
にすることでアクセスに成功した。ほかのブラウザやcurlなどからは localhost
で接続できているのに、なぜだろう。