食べチョク開発者ブログ

食べチョクエンジニアによるプロダクト開発ブログ

会社の支給PCがMacBook Pro M1なので、新しく開発環境を構築した話

こんにちは。

今年の年始からジョインした遠藤です。

さて、入社したところ会社支給の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を除外すればインストールできます。

Building Ruby on arm64 macOS

この問題が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

ということで、イメージとして対応していないです。

no matching manifest for linux/arm64/v8 in the manifest list entries · Issue #5142 · docker/for-mac · GitHub

が、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

Docker Hub

ElasticSearch/Redisに関しては問題なかったので、割愛させていただきます。

結論

正直なんとか開発状態までは漕ぎ着けれるのですが、どっちかというと現場で作業を行う場合に最新のバージョンになっていないことが多いので、そこをどうするかというのが、ポイントになるかと思います。

明らかに対応外なら、割り切って最新のを使うようにするしかないです。

Dockerの場合は、利用できない可能性もあるのでそこも割り切るしかないのかなと思います。

この辺りで本番環境と乖離が起こる可能性が高いので、どこまでを許容とするか、あるいは本番環境を合わせるかになるのかなと思います。

また、今回は先人の知恵があり、なんとかなりました。

  • 解決方法を書いてくれている方
  • M1に対応しようとOSSで対応している方

など、実際に対応されている方には、感謝しかありません。

よく言われていることですが、開発環境、ライブラリは常日頃から最新化しておかないと苦労する を痛感します。

こういった問題に解決するためにも今はチームとして頑張っています。

※この記事を書いている間にもRuby 2.6.6にアップデートし、今はRuby 2.7系にアップデートに取り組んでいます。

弊社ではM1 Macbook Proで開発をするエンジニアを募集しております。

www.wantedly.com