LoginSignup
3
0

More than 1 year has passed since last update.

Apple Silicon Dockr 上での Failed to initialize inotify (Errno::ENOSYS) を根本的に回避する方法

Last updated at Posted at 2023-03-21

Rails に限らず、 Ruby 製の WebFreamwork を Apple Silicon の Docker 上で使っていると下記のエラーに遭遇することがあります。

/var/www/bundle/ruby/3.0.0/gems/rb-inotify-0.10.1/lib/rb-inotify/notifier.rb:69:in `initialize': Function not implemented - Failed to initialize inotify (Errno::ENOSYS)

私の場合 M2 MacBook Air 上の Docker で middleman を使おうとしてこのエラーに遭遇しました。
だいぶ悩まされましたが、多分これで根本解決だという方法を見つけたので、メモとして残しておきます。
おそらくですが、 Rosetta2 がない環境でもこれで動くと思います。

追記

一晩明けて、上記エラーが出ない最小条件を探っていたのですが、どうも Ruby のイメージを arm64/v8 にするだけでいい様です(gem のインストール場所だけ解決する必要があります)。
でもまぁ一応調べたことは調べたことなので、削除はせずに残しておきます。

Ruby のイメージを arm64/v8 にする

上記からダウンロードした Ruby のイメージを使いましょう。

docker-compose.yml に platform を追加する

docker-compose.yml
version: "3.9"

services:
  middleman:
    build: .
    platform: linux/arm64/v8
    command: bundle exec middleman server
    volumes:
      - ./:/var/www
    ports:
      - "4567:4567"

のように、 platform: linux/arm64/v8 を付け足しましょう。

rb-fsevent という gem のバージョンを 0.11.2 以上にする

この rb-fsevent という gem はバイナリを含んだ gem なのですが、そのバイナリが arm64 に対応するようにコンパイルされ直したのが 0.11.0 以上のようです。

だから多分 0.11.0 でも動くとは思うのですが、私が動作確認しているのは 0.11.2 なので章タイトルはそう書かせていただきました。

Bundle を arm64 用に設定する

$ bundle lock --add-platform aarch64-linux

このコマンドを実行すると、 Gemfile.lock に「今使ってるのは arm64 だよー」と書き込んでくれます。

Docker 上の bundle_path を永続化する

普段 rubylang/ruby の Docke Image を使っていると気づかないハマりどころなのですが、先ほど紹介した arm64/v8 をはじめとした Docker 公式をベースにした Docker Image は BUNDLE_PATH が /usr/local/bundle に固定されている様です。
この設定を外すのも悪くはないのですが、個人的にはこういう設定をわざわざ入れてきているのならそれに沿った方がいいだろうと思ったので、パスの設定はそのまま永続化だけすることにしました。
方法は以下の通りです。

docker-compose.yml
version: "3.9"

services:
  middleman:
    build: .
    platform: linux/arm64/v8
    command: bundle exec middleman server
    volumes:
      - ./:/var/www
      - installed_gem:/usr/local/bundle
    ports:
      - "4567:4567"
volumes:
  installed_gem:

上記のように volumes の設定を追加しましょう。

まとめ

ここまでやって、ちゃんと docker compose run --rm container_name bundle install をしてからフレームワークを動かしてみると、冒頭のエラーは出なくなっているかと思います。

そもそもの Ruby のイメージを arm64/v8 にするというところが1番のキモだと思っています。

このメモが誰か他の人のお役に立てば幸いです。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0