Ruby
Rails
Mac
development
mastodon

Vagrant や Docker を使わずに macOS でマストドンの開発環境を構築する

More than 1 year has passed since last update.

なぜ Vagrant を使わないのか

Vagrant を使うメリットは、以下が考えられます。

  • macOS 直の環境を汚すことなく開発環境を整えられる
  • Linux の環境を使用できるので、production と同じ環境にすることができる
  • 真っ白な状態でインストールできるので、既存の環境による問題にハマることが少ない
  • 特にマストドンの場合は予め Vagrant がサポートされているので、環境構築がとても簡単

Vagrant を使うデメリットは、以下が考えられます。

  • CPU やメモリに制限があり、処理が遅い
  • 開発を行う前に VM を起動する必要があり、時間がかかる

CPU やメモリに制限がある、という点が最もネックで、特にマストドンは、CSS や JS を変更した際に Webpacker のコンパイルが走ります。これが VM 上 (Vagrant) だとかなり時間がかかります。

ちょっと変更するだけでもかなり時間がかかり、さらに、もともと Rails の開発を行うだけでもそれなりにパワーが必要になるので、今回は Mac のパワーを最大限に使用するために、Vagrant を使用しないことにしました。

頻繁にマストドンの開発を行う場合は、最初の一回の環境構築を楽にするより、その時その時の開発をスムーズに行えるようになったほうが効率的だと思います。

なぜ Docker を使わないのか

この理由は、マストドンの公式ドキュメントに記載されています。以下は、公式ドキュメントからの引用です。

Don't use Docker to do development. It's a quick way to get Mastodon running in production, it's really really inconvenient for development. Normally in Rails development environment you get hot reloading of backend code and on-the-fly compilation of assets like JS and CSS, but you lose those benefits by compiling a Docker image. If you want to contribute to Mastodon, it is worth it to simply set up a proper development environment.

Development guide

日本語に要約された記事を見つけましたので、引用します。

Dockerを開発環境では使わないでください。プロダクションで素早くマストドンを動かすにはよいのですが、開発には本当に不便です。大抵Railsの開発ではリアルタイムでリロードしてJSやCSSのコンパイルもリアルタイムに行うことができます。しかしDockerだとその良さが失われます。

マストドン開発環境のMacへの構築方法|サクサク開発!ユーザ増!

これはマストドンの開発に限ったことではなく、基本的に Docker は production で使用するものだと個人的には考えています。

設定を変更するなどして Rails サーバを再起動しないといけないとき、Docker だと、コンテナをストップして、もう一度アップするのに結構時間がかかります。

Docker も、macOS 直の環境を汚すことは防げますし、構築も簡単ですが、やはりパフォーマンスという点では、かなり劣ります。

macOS にマストドンの環境を構築

以上の理由から、Vagrant や Docker を使用せずに、macOS 直の環境にマストドンを構築していきます。

目次

リポジトリをフォークしてクローン

マストドンの公式リポジトリにアクセスして、リポジトリをフォークします。

fork_mastodon.png

フォークすると、ログインしているユーザのリポジトリ一覧に、フォークされたマストドンのリポジトリが追加されます。例えば僕の場合は https://github.com/noraworld/mastodon が、フォークされたマストドンのリポジトリになります。

フォークされたリポジトリを、コマンドラインでクローンします。ユーザ名の部分は各自置き換えてください。

$ git clone git@github.com:noraworld/mastodon.git

次に、本家のリポジトリを upstream に追加します。これにより、フォークしたリポジトリを、本家の最新のリポジトリに追従することができるようになります。

$ git remote add upstream git@github.com:tootsuite/mastodon.git

本家のリポジトリに追従する場合

フォークした直後は、本家とフォークしたリポジトリが同じ状態になっていると思うのでこれで OK ですが、しばらく経って本家のリポジトリが更新された場合は、以下のコマンドで本家のリポジトリに追従します。

$ git fetch upstream
$ git merge upstream/master

Ruby のインストール

まずは rbenv と rbenv-build をインストールします。

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ cd ~/.rbenv && src/configure && make -C src
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ exec $SHELL -l
$ type rbenv
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

次に、rbenv を使って Ruby をインストールします。マストドンで使用する Ruby のバージョンは、.ruby-version というファイルに記載されています。

$ cd path/to/mastodon
$ cat .ruby-version
2.4.2

今回は 2.4.2 と表示されたので、Ruby 2.4.2 をインストールします。

$ rbenv install 2.4.2
$ rbenv rehash
$ rbenv global 2.4.2

マストドンのディレクトリで以下を実行して、Ruby がインストールされていることを確認してください。

$ ruby -v
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-darwin16]

参考: 【CentOS7(+Ubuntu16)】Ruby / Rails のインストールから Rails サーバの起動までの(ほぼ)完全ガイド

Yarn のインストール

Node と NPM をインストールします。Node をインストールすると NPM もインストールされます。

$ git clone https://github.com/riywo/ndenv ~/.ndenv
$ echo 'export PATH="$HOME/.ndenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(ndenv init -)"' >> ~/.bashrc
$ exec $SHELL -l
$ git clone https://github.com/riywo/node-build.git $(ndenv root)/plugins/node-build

インストールする Node のバージョンは、6.x の最終バージョンで良いかと思います。Node のバージョン一覧を調べるには以下のコマンドを実行します。

$ ndenv install -l

現時点では、6.x の最終バージョンは、v6.11.5 だったので、Node v6.11.5 をインストールします。バージョンは更新されるので、上記のコマンドで確認してください。

$ ndenv install v6.11.5
$ ndenv rehash
$ ndenv global v6.11.5

Node と NPM がインストールされていることを確認してください。

$ node -v
v6.10.3
$ npm -v
3.10.10

Node と NPM がインストールされたら、NPM を使用して Yarn をインストールします。

$ npm install -g yarn

参考: ndenv を使用して複数のバージョンの Node.js を管理する方法と基本的な使い方

bundle install

まずは必要なライブラリを brew でインストールします。

$ brew install autoconf ffmpeg gcc gdbm imagemagick libffi libidn libxml2 libxslt libyaml openssl pkg-config protobuf readline

抜け落ちているライブラリがありましたら、教えていただけると嬉しいです。

次に、ライブラリのパスを指定しないと、うまくインストールすることができない Ruby のライブラリを、gem で個別にインストールします。

$ gem install nokogiri -v 'x.x.x' -- --use-system-libraries --with-xml2-include=/usr/local/opt/libxml2/include/libxml2
$ gem install nokogumbo -v 'x.x.x' -- --use-system-libraries --with-xml2-include=/usr/local/opt/libxml2/include/libxml2
$ gem install idn-ruby -- --with-idn-dir=/usr/local/Cellar/libidn/x.xx

伏せ字になっている箇所は、それぞれのライブラリのバージョンを指定してください。nokogiri と nokogumbo に関しては、Gemfile に記載されているバージョン、idn-ruby に関しては、以下のコマンドを実行した際のバージョンを、それぞれ指定します。

$ idn --version

参考: bundle installでnokogiriとnokogumboが入らない
参考: macOS で idn-ruby がインストールできないときの解決法

ここまでできたら、bundle install を実行します。

$ bundle install

必要な Ruby のライブラリがインストールされます。エラーが表示されなければ OK です。

yarn install

yarn install を実行します。

$ yarn install --pure-lockfile

PostgreSQL のインストール

PostgreSQL をインストールします。

$ brew install postgresql

データベースの初期設定を行います。

$ initdb /usr/local/var/postgres -E utf8

PostgreSQL を起動します。

$ brew services start postgresql

起動したかどうかは、brew services list でも確認できますが、こちらは DB エラーで接続できていなくても、起動していると表示されてしまうので、DB のプロセスが起動できていることをちゃんと確認します。

$ ps -ef | grep postgresql | grep -v grep

起動できていなかった場合は、こちらを参考にしてみてください。

Redis のインストール

Redis をインストールします。

$ brew install redis

Redis を起動します。

$ brew services start redis

以下のコマンドで、Redis プロセスが起動していることを確認します。

$ ps -ef | grep redis | grep -v grep

データベースのセットアップ

初回のみ、データベースのセットアップを行います。

$ rails db:setup

サーバを起動

これで環境は整ったので、サーバを起動して確認してみます。rails server でも良いのですが、開発中は foreman が便利なので、foreman を使用します。まずは foreman をインストールします。

$ gem install foreman

foreman でサーバを起動します。

$ foreman start

起動中に以下のウィンドウが表示されたら、「許可」をクリックします。

allow_ruby_network_connection.png

アクセス可能になるタイミングは、webpack: Compiled successfully. と表示され、そのままの状態 (コマンド入力のプロンプトに戻らない状態) になったときです。

http://localhost:3000 にアクセスして、ウェルカムページが表示されたら成功です! お疲れさまでした。

ログイン

development 環境では、admin というユーザがすでに用意されています。

data value
メールアドレス admin@localhost:3000
パスワード mastodonadmin

本家にプルリクエストを送信

Ctrl-C を押して、一旦 foreman を停止させます。

そのまま開発を行ってしまうと master ブランチを編集してしまうことになるので、ブランチを切ります。ブランチ名は、変更を行った内容をわかりやすく短縮したものにすると良いです。

例えば、プライバシーポリシーに関する項目の、日本語翻訳の追加をするなら、i18n-ja-terms などとすると良いでしょう。

$ git branch i18n-ja-terms
$ git checkout i18n-ja-terms

日本語翻訳の場合は特に必要ないかもしれませんが、Ruby のコードを編集した場合は、テストの実行とコーディングスタイルが正しいかどうかの確認を行いましょう。

$ rspec
$ rubocop

ファイルを変更したらコミットして、フォークした自分のリポジトリにプッシュします。あとは、GitHub のページから、プルリクエストを送信すれば OK です。