こんにちは。
今年の年始からジョインした遠藤です。
さて、入社したところ会社支給のMacBook ProがM1チップのものでした。
はい、現状は開発環境で苦労するとか色々噂を聞くやつです。
実際に試したのですが、
- 現状の開発環境構築スクリプト、手順書が一切使えない
- VitualBox, Vagrantは利用不可
- Dockerは利用可能ではあるが、一部イメージが対応されてない
- 古いパッケージは動かす手段がない
などなど、通常ではぶつからない問題にぶつかります。
食べチョクでは、
- Ruby
- Node.js
- MySQL
- Redis
- ElasticSearch
- Kibana
を利用しています。
この辺りをメインに話つつ、Intel版とこんな風に違うのかっていう辺りの雰囲気を感じ取っていただければと思います。
どこに開発環境を構築するか
まず、どこで開発環境を構築するかを考えてみたいと思います。
- ローカルで開発環境を作る
- 仮想化ソフトウェア上で作る
- VirtualBox🙅♂️
- Docker
- サーバー立ててその中に開発環境を作成して、リモートで作業する
この3種類になると思いました。
支給されたPCだとローカルに開発環境を構築される方が多いのかなって印象が多いのですが、どうなのでしょうか。
私は支給されたPCだとローカルに開発環境を構築したい派なので、ローカルでの開発環境構築をひとまず目標にしました。
今回は「ローカルで開発環境を作る」「仮想化ソフトウェア上で作る」で試しました。
では、開発環境の構築をしていきます。
ローカルで開発環境を作る
ここから実際に行ったことを記述していきたいと思います。
homebrew
みんな大好きのhomebrewですが、きちんと公式のドキュメントを読みましょう。
インストールする場所がm1 macの場合は別になっています。
mkdir /opt/homebrew && curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew echo "export PATH=/opt/homebrew/bin:$PATH" >> ~/.zshrc source .zshrc
However do yourself a favour and install to /usr/local on macOS Intel, /opt/homebrew on macOS ARM, and /home/linuxbrew/.linuxbrew on Linux. Some things may not build when installed elsewhere. One of the reasons Homebrew just works relative to the competition is because we recommend installing here. Pick another prefix at your peril!
Installation — Homebrew Documentation
Intel版ならディレクトリを明示するとかなかったので、いつもと違うなっていうことを、最初から感じさせてもらえます。
rbenv
Rubyのバージョン管理ツールのrbenvです。
こちらがないとRubyのバージョン管理で困るので、導入しましょう。
GitHub - rbenv/rbenv: Groom your app’s Ruby environment
brew install rbenv
rbenv init
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash
ここまでは問題なくいきます。
さて、待望のインストールをします!?
rbenv install 2.5.7 Downloading openssl-1.1.1i.tar.gz... -> https://dqw8nmjcqpjn7.cloudfront.net/e8be6a35fe41d10603c3cc635e93289ed00bf34b79671a3a4de64fcee00d5242 Installing openssl-1.1.1i... Installed openssl-1.1.1i to /Users/xxx/.rbenv/versions/2.5.7 Downloading ruby-2.5.7.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.7.tar.bz2 Installing ruby-2.5.7... WARNING: ruby-2.5.7 is nearing its end of life. It only receives critical security updates, no bug fixes. ruby-build: using readline from homebrew BUILD FAILED (macOS 11.0.1 using ruby-build 20201225) Inspect or clean up the working tree at /var/folders/np/m8mjm0q52njgyqc6kp0b_zw80000gn/T/ruby-build.20210110220451.39283.BzZl54 Results logged to /var/folders/np/m8mjm0q52njgyqc6kp0b_zw80000gn/T/ruby-build.20210110220451.39283.log Last 10 log lines: compiling ../.././ext/psych/yaml/reader.c 3 warnings generated. compiling ../.././ext/psych/yaml/emitter.c compiling ../.././ext/psych/yaml/parser.c linking shared-object date_core.bundle 5 warnings generated. linking shared-object zlib.bundle 1 warning generated. linking shared-object psych.bundle make: *** [build-ext] Error 2
ログファイルを確認します。
compiling qsort.c linking shared-object -test-/vm/at_exit.bundle linking shared-object -test-/wait_for_single_fd.bundle compiling closure.c compiling nofree.c compiling conversions.c compiling zlib.c installing default libraries compiling fiddle.c compiling psych_to_ruby.c closure.c:264:14: error: implicit declaration of function 'ffi_prep_closure' is invalid in C99 [-Werror,-Wimplicit-function-declaration] result = ffi_prep_closure(pcl, cif, callback, (void *)self); ^ 1 error generated. make[2]: *** [closure.o] Error 1 make[2]: *** Waiting for unfinished jobs....
なんか今までにあまり起こったことのないエラーに遭遇します。
ffiでエラーが起こっているのですが、libffiを除外すればインストールできます。
この問題が2020/6/30に解決されていることに感動を受けつつ、除外しましょう。
RUBY_CFLAGS=-DUSE_FFI_CLOSURE_ALLOC rbenv install 2.5.7
コマンド自体はissueを参考にさせていただきました。(先人に感謝)
2.6.6 on ARM64 · Issue #1699 · rbenv/ruby-build · GitHub
Ruby3.0の場合はなんの問題もなくインストールできます。
MySQL
brew install mysql@5.7 echo 'export PATH="/opt/homebrew/opt/mysql@5.7/bin:$PATH"' >> ~/.zshrc brew services start mysql@5.7
正直ここは何も問題がないので、休憩ゾーンになります。
Redis
brew install redis
brew services start redis
これも特に問題はありません。
Node.js
Node.jsは今のところversion 15以上じゃないと対応されてない状態なので、ここは素直にversion 15を使いました。
webpackのコンパイルでしか利用しないので、まぁ、いいかという気持ちもあり。。。
Nodejs 14.x doesn't compile on ARM OSX (M1) · Issue #36161 · nodejs/node · GitHub
弊社ではnodebrewを利用していたので、下記を参考にさせていただきました。
brew install nodebrew echo "export PATH=$HOME/.nodebrew/current/bin:$PATH" >> ~/.zshrc
vim $(which nodebrew) sub system_info { my $arch; my ($sysname, $machine) = (POSIX::uname)[0, 4]; if ($machine =~ m/x86_64|arm64/) { $arch = 'arm64'; } elsif ($machine =~ m/i\d86/) { ... nodebrew compile v15.5.0
M1 Mac を購入して arm64 縛りでインストールしたもの (更新中) - アルパカ三銃士
ElasticSearchのインストール
弊社では検索エンジンにElasticSearchを利用しているので、ElasticSearchをインストールします。
brew install --build-from-source elasticsearch ... ==> Installing dependencies for elasticsearch: openjdk and gradle ==> Installing elasticsearch dependency: openjdk ==> Patching ==> Applying f80a6066e45c3d53a61715abfe71abc3b2e162a1.patch patching file src/hotspot/share/runtime/sharedRuntime.cpp Hunk #1 succeeded at 2850 (offset -6 lines). ==> Applying 4622a18a72c30c4fc72c166bee7de42903e1d036.patch patching file src/java.desktop/macosx/native/libawt_lwawt/awt/CSystemColors.m ==> ./configure --without-version-pre --without-version-opt --with-version-build=9 --with-toolchain-path=/usr/bin --with-sysroot=/Library/Developer/Com Last 15 lines from /Users/endo/Library/Logs/Homebrew/openjdk/01.configure: checking for stdlib.h... yes checking for string.h... yes checking for memory.h... yes checking for strings.h... yes checking for inttypes.h... yes checking for stdint.h... yes checking for unistd.h... yes checking stdio.h usability... yes checking stdio.h presence... yes checking for stdio.h... yes checking size of int *... 8 configure: The tested number of bits in the target (64) differs from the number of bits expected to be found in the target (32) configure: error: Cannot continue. /private/tmp/openjdk-20210110-26180-4xtn4y/jdk15u-jdk-15.0.1-ga/build/.configure-support/generated-configure.sh: line 82: 5: Bad file descriptor configure exiting with result code 1 Do not report this issue to Homebrew/brew or Homebrew/core! These open issues may also help: Cassandra 3.11.9_1 crashes in openjdk@8 JVM https://github.com/Homebrew/homebrew-core/issues/66462 openjdk: Add support for Apple silicon https://github.com/Homebrew/homebrew-core/pull/65670 OpenJDK is somewhat broken on newer MacOS instances, console is flooded with errors when using JMeter, AdoptOpenJDK has no issues https://github.com/Homebrew/homebrew-core/issues/66953
案の定エラーになります。
原因はOpenJDKがサポートされてないので、利用できません。
https://github.com/Homebrew/homebrew-core/pull/65670
このPR早くマージしてくれ!という気持ちもありつつ、OpenJDKはZuluがM1対応しているので、そちらを利用します。
Support of Java Builds of OpenJDK for Apple Silicon | Azul
Java Download | Java 8, Java 11, Java 13 - Linux, Windows & macOS
※記事執筆中にマージされていましたので、この問題は解決していましたが、https://github.com/Homebrew/homebrew-core/pull/69029で別の問題が発生しています
ElasticSearchはソースコードからビルドするように変更します。
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-darwin-x86_64.tar.gz wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.10.1-darwin-x86_64.tar.gz.sha512 shasum -a 512 -c elasticsearch-7.10.1-darwin-x86_64.tar.gz.sha512 tar -xzf elasticsearch-7.10.1-darwin-x86_64.tar.gz cd elasticsearch-7.10.1/
Javaの参照先をZuluに追加します。
Set up Elasticsearch | Elasticsearch Reference [7.10] | Elastic
echo "export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-15.jdk/Contents/Home" >> ~/.zshrc
これでbin/elastic search
で動くのですが、xpackがサポートされないので、コンフィグから外しましょう。
org.elasticsearch.ElasticsearchException: X-Pack is not supported and Machine Learning is not available for [darwin-aarch64]; you can use the other X-Pack features (unsupported) by setting xpack.ml.enabled: false in elasticsearch.yml
Kibana
ElasticSearchを入れるので、Kibanaも入れましょう。
homebrew経由でインストールしようとすると、案の定エラーになるのでソースコードからビルドします。
curl -O https://artifacts.elastic.co/downloads/kibana/kibana-7.10.1-darwin-x86_64.tar.gz curl https://artifacts.elastic.co/downloads/kibana/kibana-7.10.1-darwin-x86_64.tar.gz.sha512 | shasum -a 512 -c - tar -xzf kibana-7.10.1-darwin-x86_64.tar.gz cd kibana-7.10.1-darwin-x86_64/ bin/kibana
ここまで揃うと、なんとかbundle exec rails server
までは辿りつけると思います。
ここまでがローカル開発環境編です。
仮想化ソフトウェア上で作る
現状はVirtual Boxが対応していないので、Docker Previewが頼みの綱になります。
Docker Previewはrosettaが現状は必要になるので、rosettaをインストールします。
softwareupdate --install-rosetta
Docker Previewのダウンロードは下記にリンクがあるので、そちらかダウンロードします。
Download and Try the Tech Preview of Docker Desktop for M1 - Docker Blog
ここではうまくいきづらいものだけ紹介します。
docker-composeを利用することを前提にしていきます。
MySQL
設定ファイルです。
services: mysql: image: mysql:5.7
docker-compose up Pulling mysql (mysql:5.7)... 5.7: Pulling from library/mysql ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries
ということで、イメージとして対応していないです。
が、issueを見るとMariaDB
を使うか、特定のIntelのやつを使えばいけるということで、変更します。
services:
mysql:
image: mysql:5.7@sha256:b3b2703de646600b008cbb2de36b70b21e51e7e93a7fca450d2b08151658b2dd
Kibana
arm64のイメージがないので、利用できませんでした。
docker-compose up WARNING: Found orphan containers (tabechoku_elasticsearch, tabechoku_redis, tabechoku_mysql) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up. Pulling kibana (kibana:7.10.1)... 7.10.1: Pulling from library/kibana ERROR: no matching manifest for linux/arm64/v8 in the manifest list entries
ElasticSearch/Redisに関しては問題なかったので、割愛させていただきます。
結論
正直なんとか開発状態までは漕ぎ着けれるのですが、どっちかというと現場で作業を行う場合に最新のバージョンになっていないことが多いので、そこをどうするかというのが、ポイントになるかと思います。
明らかに対応外なら、割り切って最新のを使うようにするしかないです。
Dockerの場合は、利用できない可能性もあるのでそこも割り切るしかないのかなと思います。
この辺りで本番環境と乖離が起こる可能性が高いので、どこまでを許容とするか、あるいは本番環境を合わせるかになるのかなと思います。
また、今回は先人の知恵があり、なんとかなりました。
- 解決方法を書いてくれている方
- M1に対応しようとOSSで対応している方
など、実際に対応されている方には、感謝しかありません。
よく言われていることですが、開発環境、ライブラリは常日頃から最新化しておかないと苦労する を痛感します。
こういった問題に解決するためにも今はチームとして頑張っています。
※この記事を書いている間にもRuby 2.6.6にアップデートし、今はRuby 2.7系にアップデートに取り組んでいます。
弊社ではM1 Macbook Proで開発をするエンジニアを募集しております。