【Rails】M1チップ搭載MacでRuby on Railsの開発環境構築

はじめに

M1チップ搭載MacにRuby on Railsの開発環境を構築する手順を記載します。

  • MacBook Air (M1, 2020)
  • macOS Monterey 12.3.1

Homebrew

Homebrewのインストール

公式サイトに記載されているインストールコマンドを実行します。

% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Homebrewのパスを追加

環境変数$PATHにHomebrewのパスを追加します。なお、以下はZ Shellを使っている場合の設定例です。Z Shellではなく別のシェルを使っている場合は適宜読み替えてください。今回は.zshenvで環境変数の設定をしていますが、他の設定ファイルでも大丈夫です。Z Shellの設定ファイルを厳密に使い分けたい場合は、以下のページなどを参考にしてください。

# 設定前の確認
% echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

# Homebrewのパスを追加
% echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshenv

# 設定ファイルを反映
% source ~/.zshenv

# 設定後の確認
% echo $PATH    
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

~/.zshenv

export PATH="/opt/homebrew/bin:$PATH"

設定後、以下のコマンドを実行しHomebrewのバージョンが確認できればOKです。

% brew --version
Homebrew 3.4.10

rbenv

rbenvのインストール

以下のコマンドを実行し、rbenvをインストールします。なお、rbenvをインストールすると一緒にruby-buildもインストールされます。

# rbenvのインストール
% brew install rbenv

# rbenvの確認
% brew list rbenv

# ruby-buildの確認
% brew list ruby-build

rbenvのシェル設定

以下のコマンドを実行し、表示された指示に従ってシェルを設定します。以下はZ Shellの場合の設定例です。

# 設定前の確認
% which ruby
/usr/bin/ruby

# 初期化コマンド
% rbenv init
# Load rbenv automatically by appending
# the following to ~/.zshrc:

eval "$(rbenv init - zsh)"

# 設定を追加
% echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc

# 設定を反映
% source ~/.zshrc

# 設定後の確認
% which ruby
/path/to/.rbenv/shims/ruby

~/.zshrc

eval "$(rbenv init - zsh)"

eval "$(...)"は、カッコ内の文字列を評価・連結して実行するコマンドです。rbenv init - zshは、Z Shell用のrbenv初期化コマンドです。

% rbenv init - zsh
export PATH="/path/to/.rbenv/shims:${PATH}"
export RBENV_SHELL=zsh
source '/opt/homebrew/Cellar/rbenv/1.2.0/libexec/../completions/rbenv.zsh'
command rbenv rehash 2>/dev/null
rbenv() {
  local command
  command="${1:-}"
  if [ "$#" -gt 0 ]; then
    shift
  fi

  case "$command" in
  rehash|shell)
    eval "$(rbenv "sh-$command" "$@")";;
  *)
    command rbenv "$command" "$@";;
  esac
}

1行目で環境変数$PATHにrbenvのパスを追加しています。この初期化コマンドを実行しておかないと、rbenvでインストールしたRubyバージョンを使うことはできません。

Ruby

Rubyのインストール(失敗)

M1チップ搭載のMacでは以下のコマンドを実行しただけではRubyをインストールすることはできません。以下のようなエラーメッセージが表示され、インストールに失敗してしまいます。

% rbenv install 2.6.3
Downloading openssl-1.1.1n.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a
Installing openssl-1.1.1n...
Installed openssl-1.1.1n to /path/to/.rbenv/versions/2.6.3

Downloading ruby-2.6.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2
Installing ruby-2.6.3...
ruby-build: using readline from homebrew

BUILD FAILED (macOS 12.3.1 using ruby-build 20220426)

Inspect or clean up the working tree at /var/folders/44/kkybmqys33n9j6_y00q6vqm80000gn/T/ruby-build.20220505131724.16336.ZD48lr
Results logged to /var/folders/44/kkybmqys33n9j6_y00q6vqm80000gn/T/ruby-build.20220505131724.16336.log

Last 10 log lines:
1340 warnings generated.
linking shared-object objspace.bundle
5 warnings generated.
4 warnings generated.
linking shared-object zlib.bundle
1 warning generated.
linking shared-object psych.bundle
422 warnings generated.
linking shared-object date_core.bundle
make: *** [build-ext] Error 2

M1チップ搭載のMacでRubyをインストールするには、インストールコマンドを実行する前に環境変数の設定を行う必要があります。2通りの方法があるので、うまくいくほうを試してみてください。

なお、Rubyのバージョンによってはエラーが出ずインストールできることもあるようですが、将来、新しいRubyバージョンのインストール時に同じエラーを出さないために、以下の対応を行っておくことをおすすめします。

環境変数の設定:方法①

環境変数$RUBY_CFLAGSに以下のいずれかの値を設定します。

# 以下のいずれかを実行
% echo 'export RUBY_CFLAGS="-w"' >> ~/.zshenv
% echo 'export RUBY_CFLAGS="-Wno-error=implicit-function-declaration"' >> ~/.zshenv
% echo 'export RUBY_CFLAGS="-DUSE_FFI_CLOSURE_ALLOC"' >> ~/.zshenv

# 設定を反映
% source ~/.zshenv

~/.zshenv

# 以下のいずれか
export RUBY_CFLAGS="-w"
export RUBY_CFLAGS="-Wno-error=implicit-function-declaration"
export RUBY_CFLAGS="-DUSE_FFI_CLOSURE_ALLOC"

環境変数$RUBY_CFLAGSは、環境変数$CFLAGSの追加オプションを設定します。環境変数$CFLAGSは、CおよびC++コードをコンパイルするときにビルド・システムにコンパイラー・オプションを指定するために従来から使用されている環境変数の1つです。

環境変数の意味も設定値の意味もよくわかっていませんが、私の環境では上記を行うことでRubyをインストールできるようになりました。

環境変数の設定:方法②

rbenv (ruby-build)で使用されるOpenSSLの環境変数を設定します。rbenv (ruby-build)はインストールのたびにOpenSSLをダウンロードしています。

% rbenv install 2.6.3
Downloading openssl-1.1.1n.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a
Installing openssl-1.1.1n...
Installed openssl-1.1.1n to /path/to/.rbenv/versions/2.6.3
...

そもそも、macOSはHigh Sierraから標準のSSL/TLSライブラリとしてLibreSSLを使用しているため、OpenSSLはインストールすらされていない可能性があり(別の依存関係でインストールされている場合もある)、インストールのたびにダウンロードするのが確実ということなんでしょう。

rbenv (ruby-build)で使用するOpenSSLをHomebrewでインストールしたOpenSSLに変更するには以下の手順を行います。

# 設定前の確認
% openssl version
LibreSSL 2.8.3

# OpenSSLのインストール
% brew install openssl@1.1

# 環境変数の設定
% echo 'export PATH="$(brew --prefix openssl@1.1)/bin:$PATH"' >> ~/.zshenv
% echo 'export LDFLAGS="-L$(brew --prefix openssl@1.1)/lib"' >> ~/.zshenv
% echo 'export CPPFLAGS="-I$(brew --prefix openssl@1.1)/include"' >> ~/.zshenv
% echo 'export PKG_CONFIG_PATH="$(brew --prefix openssl@1.1)/lib/pkgconfig"' >> ~/.zshenv
% echo 'export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)"' >> ~/.zshenv

# 設定の反映
% source ~/.zshenv

# 設定後の確認
% openssl version
OpenSSL 1.1.1n  15 Mar 2022

~/.zshenv

export PATH="$(brew --prefix openssl@1.1)/bin:$PATH"
export LDFLAGS="-L$(brew --prefix openssl@1.1)/lib"
export CPPFLAGS="-I/$(brew --prefix openssl@1.1)/include"
export PKG_CONFIG_PATH="$(brew --prefix openssl@1.1)/lib/pkgconfig"
export RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl@1.1)"

環境変数$RUBY_CONFIGURE_OPTSは、rbenv (ruby-build)で使用するOpenSSLを指定しています。その他の環境変数($LDFLAGS $CPPFLAGS $PKG_CONFIG_PATH)の設定は必須ではないかもしれません。$(...)は、カッコ内のコマンド結果を文字列として返します。

% brew --prefix openssl@1.1
/opt/homebrew/opt/openssl@1.1

上記の設定を行うと、インストールのたびに行っていたOpenSSLのダウンロードが行われなくなります。

% rbenv install 2.6.3
Downloading ruby-2.6.3.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.3.tar.bz2
Installing ruby-2.6.3...
ruby-build: using readline from homebrew
...

OpenSSLをインストールしたものの、やっぱりアンインストールしたい場合は以下のコマンドを実行します。

# OpenSSLのアンインストール
% brew uninstall openssl@1.1
Uninstalling /opt/homebrew/Cellar/openssl@1.1/1.1.1n... (8,089 files, 18MB)

Warning: The following openssl@1.1 configuration files have not been removed!
If desired, remove them manually with `rm -rf`:
  /opt/homebrew/etc/openssl@1.1
  ...

# 上記の指示に従って削除
% rm -rf /opt/homebrew/etc/openssl@1.1

Rubyのインストール(成功)

環境変数の設定が完了したら、改めてRubyのインストールを行います。

# Rubyのインストール
% rbenv install 2.6.3

# バージョン確認(rbenv)
% rbenv version
2.6.3 (set by /path/to/.rbenv/version)

# バージョン確認(ruby)
% ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [-darwin21]

Ruby on Rails

Ruby on Railsのインストール

以下のコマンドを実行し、Ruby on Railsをインストールします。最新バージョンをインストールしたい場合、-vオプションは不要です。

# Ruby on Railsのインストール
% gem install rails -v 6.1.3.2

# バージョン確認
% rails -v
Rails 6.1.3.2

バージョン確認コマンド実行時に以下のようなエラーメッセージが表示される場合、以下のコマンドを実行します。

# バージョン確認
% rails -v
Your Ruby version is 2.6.8, but your Gemfile specified 2.6.3

# 以下のコマンドを実行
% rbenv rehash

Bundlerのインストール

以下のコマンドを実行し、Bundlerをインストールします。最新バージョンをインストールしたい場合、-vオプションは不要です。

# Bundlerのインストール
% gem install bundler -v 2.0.2

# バージョン確認
% bundler -v                  
Bundler version 2.0.2

その他のGemのインストール

Gemfileに記述されているGemをインストールします。GitHubなどからRailsアプリをcloneし、そのRailsアプリ配下で以下のコマンドを実行します。

% bundle install

MySQL / PostgreSQL

GemfileにMySQLやPostgreSQLのGemが含まれている場合、Homebrewでインストールしてからbundle installを実行します。

# MySQLのインストール
% brew install mysql

# PostgreSQLのインストール
% brew install postgresql

MySQLやPostgreSQLをインストールする前にbundle installを実行した場合、以下のようなエラーメッセージが表示されます(MySQLの場合の例)。

% bundle install
...
Installing mysql2 0.5.3 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

...

-----
mysql client is missing. You may need to 'brew install mysql' or 'port install mysql', and try again.
-----

...

An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue.

In Gemfile:
  mysql2

GitHubのリポジトリ指定

GemfileでGitHubのリポジトリを指定している場合、以下のように修正してからbundle installを実行します。

Gemfile

 gem 'impressionist',
-  git: 'git://github.com/charlotte-ruby/impressionist.git',
+  git: 'https://github.com/charlotte-ruby/impressionist.git',
   ref: '46a582ff8cd3496da64f174b30b91f9d97e86643'

Gemfileを修正する前にbundle installを実行した場合、以下のようなエラーメッセージが表示されます。

% bundle install
fatal: remote error: 
  The unauthenticated git protocol on port 9418 is no longer supported.
Please see https://github.blog/2021-09-01-improving-git-protocol-security-github/ for more information.

...

動作確認

いよいよ最後の動作確認になりました。rails serverを起動し、Railsアプリが表示できるか確認しましょう。

復号化キーの準備

機密情報の保持にCredentialsを使っている場合、復号化キーを準備する必要があります。具体的にはRailsアプリを開発していた旧PCやRailsアプリをホスティングしているサーバーから以下の情報を取得します。

  • ファイル/path/to/app/config/master.key
  • 環境変数$RAILS_MASTER_KEY

どうしても復号化キーを準備できない場合、Credentialsの機密情報を再作成する必要があります。その場合、既存の機密情報は失われてしまうのでご注意ください。Credentialsについて詳しくは以下の記事を参照してください。

復号化キーを準備する前にrails serverを起動すると以下のようなエラーメッセージが表示されます。復号化キーが見つからないとnilが返されるため、「nilに未定義のメソッド」というエラーが発生しています。

% rails server
...
/path/to/app/config/database.yml:34:in `<main>': Cannot load database configuration:
undefined method `[]' for nil:NilClass (NoMethodError)

Action Text

RailsアプリでAction Textを使っている場合、Action Textをインストールします。

% rails action_text:install

マイグレーションの実行

マイグレーションを実行します。

% rails db:migrate

まとめ

M1チップ搭載MacにRuby on Railsの開発環境を構築する手順をまとめてみました。M1チップ搭載Macならではの事象としては、rbenvでRubyのインストールしようとした時に発生したエラーくらいでしょうか。おそらく最も詰まるポイントではないかと思います。

本記事の内容は私の環境に基づいたものになります。あくまで参考情報として参照していただければと思います。

関連記事

【Rails】Railsアップグレードまとめ
# はじめに Ruby on Railsに限らず、何らかのフレームワークを使ってWebシステムを構築している場合、フレームワークのアップグレード作業は避けて通れません。 一般的にフレームワークはバージョン毎にEOL (End of Life [...]
2022年10月1日 14:32
【Rails】ユーザー登録時に行うメールアドレス認証機能の実装方法
# はじめに ユーザー登録/解除やログイン/ログアウトといった認証機能の導入に「devise」というGemを使っている人は多いと思います。「devise」では以下のように記述するだけで、ユーザー登録時に確認メールを送付しメールアドレス認証を行う機 [...]
2022年9月24日 14:24
【Rails】モデルに列挙型(enum)を定義し、使いこなす方法
# はじめに Railsはモデルでカラム名と同名の列挙型(enum)を定義することで、カラムと列挙型の変数を紐付けることができます。カラムと列挙型の変数を紐付けると、カラムに対して様々な便利な使い方ができるようになります。 本記事では、モデ [...]
2022年9月3日 10:29
【Rails】RailsでCORSとPreflight requestの設定を行う方法
# はじめに RailsアプリをAPIサーバーとして構築するには、CORS (Cross-Origin Resource Sharing)と Preflight requestの設定を行う必要があります。APIサーバーは外部からの要求に対して処理 [...]
2022年8月27日 10:44
【Ruby】Bundlerを使ってRubyGemsを作成/公開する方法
# はじめに Bundlerを使ってRubyGemsを作成および公開する方法について説明します。Bundlerを使わずにRubyGemsを作成/公開する方法については以下の記事を参照してください。 <iframe class="hatena [...]
2022年7月12日 23:18
【Ruby】RubyGemsを作成/公開する方法
# はじめに RubyGemsを作成および公開する方法について説明します。Bundlerを使ってRubyGemsを作成する方法については以下の記事を参照してください。 <iframe class="hatenablogcard" style [...]
2022年7月11日 21:52
【Rails】Rakeタスクの基本情報と作成・実行方法
# はじめに Railsには標準でRakeというGemが同梱されています。RakeはRubyで実装されたMake(UNIX系のOSで使用できるコマンド)のようなビルド作業を自動化するツールです。Ruby Make、略してRakeというわけですね。 [...]
2022年3月7日 22:12
【Rails】モデルに外部キーを設定する方法とよく起こるエラー内容について
# はじめに Railsでモデルに外部キーを設定する方法について説明します。 # モデルに外部キーを設定する ## リレーションシップ 今回は1つのブログ記事は複数のコメントを持つ1対多のリレーションシップを例に説明します。現在は` [...]
2022年2月10日 14:18