LoginSignup
1
1

M1MacのDockerでyarn installがエラーになる件について

Posted at

はじめに

前回書いた記事「既存RailsアプリをDocker化する手順」でDocker環境を構築する過程で、
yarn install時でM1チップ特有のエラーが発生しました。
今回は備忘録も兼ねエラーについて簡単にまとめていきたいと思います。
※下記記事ではエラーが発生しないよう対応済みです。

開発環境

下記開発環境にてDocker化を行いました。

  • CPU: Apple M1
  • OS: MacOS Ventura バージョン13.3.1

各種設定

Docker化するにあたり、使用したバージョンは以下の通りです。

  • ruby: 3.0.2
  • rails: 6.0.3
  • node: 15.0.1
  • postgresql: 12.0

また、Dockerfileとdocker-compose.ymlの設定は以下の通りです。

Dockerfile
FROM node:15.0.1 as node
FROM ruby:3.0.2

COPY --from=node /opt/yarn-* /opt/yarn
COPY --from=node /usr/local/bin/node /usr/local/bin/
COPY --from=node /usr/local/lib/node_modules/ /usr/local/lib/node_modules/
RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
    && ln -fs /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npx \
    && ln -fs /usr/local/lib/node /usr/local/bin/nodejs \
    && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarn \
    && ln -fs /opt/yarn/bin/yarn /usr/local/bin/yarnpkg

RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    postgresql-client

RUN mkdir /myapp
WORKDIR /myapp

COPY package.json /myapp/package.json
COPY yarn.lock  /myapp/yarn.lock
RUN yarn install

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

COPY . /myapp
docker-compose.yml
version: '3'

services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0' &&
    ports: 
      - '3000:3000'
    volumes:
      - .:/myapp
    environment:
      - 'DATABASE_PASSWORD=postgres'
    tty: true
    stdin_open: true
    depends_on:
      - 'db'

  db:
    image: postgres:12.0
    environment:
      - POSTGRES_PASSWORD=password

エラー内容

上記Dokcerfileとdocker-compose.ymlの設定で、docker-compose buildを実行すると、
下記の通り、yarn installでエラーが発生します。
内容を見るに、/lib/ld-linux-armhf.so.3というファイルまたはディレクトリがないと
言っている模様。

terminal
=> ERROR [stage-1 11/15] RUN yarn install                                 0.2s
------
 > [stage-1 11/15] RUN yarn install:
#0 0.165 qemu-arm: Could not open '/lib/ld-linux-armhf.so.3': No such file or directory
------
failed to solve: process "/bin/sh -c yarn install" did not complete successfully: exit code: 255

解決方法

エラー内容を調べていると、どうやらアーキテクチャに問題があることが判明しました。
Dockerfileで指定した、node:15.0.1をDocker hubで調べてみると、
下図赤枠部分の通り、M1のアーキテクチャであるlinux/arm/v8には対応していない模様。

スクリーンショット 2023-06-04 21.14.25.png

よって、nodeのバージョンを以下の通り、linux/arm/v8に対応したバージョンを選択し、
再度docker-compose buildを実行します。
(※最新のバージョンを選択すると別のエラーが発生したので、今回はVer.16.13を選択)

Dockerfile
- FROM node:15.0.1 as node
+ FROM node:16.13 as node

どうやら、無事にインストールできた模様。

terminal
=> [stage-1  2/15] COPY --from=node /opt/yarn-* /opt/yarn                 0.0s
 => [stage-1  3/15] COPY --from=node /usr/local/bin/node /usr/local/bin/   0.1s
 => [stage-1  4/15] COPY --from=node /usr/local/lib/node_modules/ /usr/lo  0.2s
 => [stage-1  5/15] RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cl  0.2s
 => [stage-1  6/15] RUN apt-get update && apt-get install -y     build-es  6.2s
 => [stage-1  7/15] RUN mkdir /myapp                                       0.2s
 => [stage-1  8/15] WORKDIR /myapp                                         0.0s
 => [stage-1  9/15] COPY package.json /myapp/package.json                  0.0s
 => [stage-1 10/15] COPY yarn.lock  /myapp/yarn.lock                       0.0s
 => [stage-1 11/15] RUN yarn install                                      19.5s
 => [stage-1 12/15] COPY Gemfile /myapp/Gemfile                            0.0s
 => [stage-1 13/15] COPY Gemfile.lock /myapp/Gemfile.lock                  0.0s
 => [stage-1 14/15] RUN bundle install                                    60.9s
 => [stage-1 15/15] COPY . /myapp                                          2.0s
 => exporting to image                                                     2.2s
 => => exporting layers                                                    2.2s

あとは、docker-compose run web rails db:create db:migrate
docker-compose upを実行することで、railsアプリを無事に起動することができました🎉

参考

アーキテクチャをlinux/arm/v8に対応したものに変更する方法以外に、
platformを指定する方法でもエラーを解消することができます。
以下の通り、docker-compose.ymlplatform: linux/amd64を追記し、
docker-compose buildを実行します。
platform: linux/amd64によって、アーキテクチャをamd64に設定しています。

docker-compose.yml
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0' &&
    ports: 
      - '3000:3000'
    volumes:
      - .:/myapp
+   platform: linux/amd64
    environment:
      - 'DATABASE_PASSWORD=postgres'
    tty: true
    stdin_open: true
    depends_on:
      - 'db'

10分〜15分ほど待つと無事ビルドが完了します。
(bundle installが長く、自分は途中でインストールが失敗しているものと勘違いしていました)

terminal
=> [stage-1  2/15] COPY --from=node /opt/yarn-* /opt/yarn                 0.0s
 => [stage-1  3/15] COPY --from=node /usr/local/bin/node /usr/local/bin/   0.1s
 => [stage-1  4/15] COPY --from=node /usr/local/lib/node_modules/ /usr/lo  0.2s
 => [stage-1  5/15] RUN ln -fs /usr/local/lib/node_modules/npm/bin/npm-cl  0.3s
 => [stage-1  6/15] RUN apt-get update && apt-get install -y     build-e  36.8s
 => [stage-1  7/15] RUN mkdir /myapp                                       0.3s
 => [stage-1  8/15] WORKDIR /myapp                                         0.0s
 => [stage-1  9/15] COPY package.json /myapp/package.json                  0.0s
 => [stage-1 10/15] COPY yarn.lock  /myapp/yarn.lock                       0.0s
 => [stage-1 11/15] RUN yarn install                                      71.2s
 => [stage-1 12/15] COPY Gemfile /myapp/Gemfile                            0.0s
 => [stage-1 13/15] COPY Gemfile.lock /myapp/Gemfile.lock                  0.0s
 => [stage-1 14/15] RUN bundle install                                   565.5s
 => [stage-1 15/15] COPY . /myapp                                          3.3s
 => exporting to image                                                     2.8s
 => => exporting layers                                                    2.8s

このままdocker-compose run web rails db:create db:migrateを実行すると、
下記エラーが発生するため、config/environment/development.rb
以下の通り編集します。

terminal
rails aborted!
Errno::ENOSYS: Function not implemented - Failed to initialize inotify
config/environment/development.rb
-  config.file_watcher = ActiveSupport::EventedFileUpdateChecker
+  config.file_watcher = ActiveSupport::FileUpdateChecker

そして、docker-compose run web rails db:create db:migrate
docker-compose upを実行することで、railsアプリを起動することができます。

まとめ

最後に本記事のまとめです。

  • M1MacでDockerを使用する際は、使用するパッケージがlinux/arm/v8に対応しているか確認する
  • アーキテクチャをlinux/amd64指定することで、エラーを回避する方法もあるが、
    最適化されているlinux/arm/v8の方が動作が速い
    (特にインストールの時間はかなり違います)

以上となります。最後まで記事を読んでいただきありがとうございます。

参考文献

1
1
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
1
1