MMMブログ

Docker for Macの代わりに、Vagrant + Dockerで開発環境を構築する

このエントリーをはてなブックマークに追加

エンジニアの内山です。最近は家に引きこもって、どう森とスプラトゥーンを楽しんでいます。

今回は、Vagrant + Dockerで開発環境を構築する手順をご紹介します。

概要

Docker for Mac はパフォーマンスが悪いため、開発効率に悪くなってしまいます。原因については、以下を参照してください。

https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076/158

Docker自体が遅いわけではないため、Linux上で動かした場合は、問題になりません。

この記事では、Docker for Macの代わりに、Vagrantで動作させているLinux上でDockerを使い、開発環境を構築する方法をご紹介しています。

手順は、以下の3ステップになります。

  1. VirtualBoxとVagrantをインストールする
  2. mutagenでファイル同期する
  3. Dockerを起動する

VirtualBox と Vagrantをインストールする

Homebrewを使用しようして、必要なツールをインストールしていきます。

https://brew.sh/

VirtualBoxとVagrantとUbuntuのイメージををインストールします。

1
2
3
$ brew cask install virtualbox
$ brew cask install vagrant
$ vagrant box add ubuntu/xenial64

Dockerとmutagen(後述)用のvagrantプラグインをインストールします。

1
$ vagrant plugin install vagrant-disksize vagrant-hostsupdater vagrant-mutagen vagrant-docker-compose

vagrantで初期化します。

1
$ vagrant init ubuntu/xenial64

次に、Vagrantファイルを作成しますが、Railsプロジェクトのディレクトリに作成する必要はありません。もし、プロジェクトのgitに含めたくない場合は、Vagrant実行用のディレクトリを作成して、そこにVagrantファイルを作成すると良いでしょう。

Vagrantファイルの内容は以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Vagrant.configure('2') do |config|
config.vm.box = 'ubuntu/xenial64'

config.vm.hostname = 'my-app'

config.vm.network :private_network, ip: '192.168.50.10'

config.vm.network "forwarded_port", guest: 80, host: 80

config.vm.provider :virtualbox do |vb|
vb.gui = false
vb.cpus = 4
vb.memory = 8192
vb.customize ['modifyvm', :id, '--natdnsproxy1', 'off']
vb.customize ['modifyvm', :id, '--natdnshostresolver1', 'off']
end

config.disksize.size = '30GB'
config.mutagen.orchestrate = true

config.vm.synced_folder '### PATH_TO_PROJECT ###', '/home/vagrant/app', type: 'rsync',
rsync_auto: true,
rsync__exclude: ['.git/', 'node_modules/', 'log/', 'tmp/', 'vendor']

config.vm.provision :docker, run: 'always'
config.vm.provision :docker_compose
end

### PATH_TO_PROJECT ### の部分を、プロジェクトディレクトリの絶対パスに変更してください。

以上で、Vagrant+VirtualBoxの準備は完了です。

mutagenでファイル同期する

編集したファイルをMacとLinuxで同期させます。mutagenというツールで実現します。

以下のコマンドで、mutagenをインストールします。

1
$ brew install mutagen-io/mutagen/mutagen

mutagenの設定ファイルmutagen.ymlを作成します。作成する場所は、Vagrantfileと同じディレクトリにしてください。内容は以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
sync:
app:
mode: "two-way-resolved"
alpha: "### PATH_TO_PROJECT ####"
beta: "my-app:/home/vagrant/app"
ignore:
vcs: true
paths:
- "/node_modules"
- "/log"
- "/tmp"
- "/vendor"

### PATH_TO_PROJECT ### の部分を、プロジェクトディレクトリの絶対パスに変更してください。

これで、mutagenの設定は完了です。mutagenはVagrantのプラグイン経由で実行されます。

Dockerを起動する

Vagrantで起動したLinuxにログインします。

1
2
$ vagrant up
$ vagrant ssh

Unable to monitor filesystemというエラーが発生する場合があるので、以下のコマンドを実行しておき、防止します。

1
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

Vagrantの中で、Dockerを起動します。以下のコマンドは、プロジェクトディレクトリにdocker-compose.ymlが存在している場合の例です。

1
2
$ cd app
$ docker-compose up

以上で、完了です。

体感的に、Docker for Macよりも高速に実行されていることが確認できると思います。

他の改善方法

Docker for Macのパフォーマンス改善に関する方法は、他にも以下のようなものがあります。

Macを使わずにLinux PCを使う

Macにこだわらなければ、LinuxPCを使うことも選択肢の一つです。移行コストが気にならなければ、この方法を選択できます。

docker-syncを使う

未検証ですが、docker-syncを使う方法もあるそうです。
https://github.com/EugenMayer/docker-sync/wiki

Dockerを使わない

そもそもDockerを使わない選択肢もあります。この方法は、チームのメンバー間で環境差異が出るのが懸念点です。しかし、フロントエンド開発であれば、ほとんど問題ないかもしれません。

フロントエンドの開発環境に Docker は不要(少なくともMacでは)
https://mizchi.hatenablog.com/entry/2019/04/07/074634

バックエンド開発については、DBなどのコンポーネントが必要な場合が多いため、Dockerはほぼ必須かと思います。

おわりに

Docker for Macのパフォーマンスは、開発効率にかなりの悪影響を及ぼすレベルです。開発を進める前に、改善することをおすすめします。

参考

このエントリーをはてなブックマークに追加

お問い合わせ

見積もり依頼や詳しいご相談など、クラウド・AWSに関する困りごとをお気軽にご相談ください。
以下のお問い合わせ先から受け付けています。

お問合わせはこちら

※通常1営業日内にご回答いたします。