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ステップになります。
- VirtualBoxとVagrantをインストールする
- mutagenでファイル同期する
- Dockerを起動する
VirtualBox と Vagrantをインストールする
Homebrewを使用しようして、必要なツールをインストールしていきます。
VirtualBoxとVagrantとUbuntuのイメージををインストールします。
$ brew cask install virtualbox
$ brew cask install vagrant
$ vagrant box add ubuntu/xenial64
Dockerとmutagen(後述)用のvagrantプラグインをインストールします。
$ vagrant plugin install vagrant-disksize vagrant-hostsupdater vagrant-mutagen vagrant-docker-compose
vagrantで初期化します。
$ vagrant init ubuntu/xenial64
次に、Vagrantファイルを作成しますが、Railsプロジェクトのディレクトリに作成する必要はありません。もし、プロジェクトのgitに含めたくない場合は、Vagrant実行用のディレクトリを作成して、そこにVagrantファイルを作成すると良いでしょう。
Vagrantファイルの内容は以下のようになります。
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をインストールします。
$ brew install mutagen-io/mutagen/mutagen
mutagenの設定ファイルmutagen.yml
を作成します。作成する場所は、Vagrantfileと同じディレクトリにしてください。内容は以下のようになります。
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にログインします。
$ vagrant up
$ vagrant ssh
Unable to monitor filesystem
というエラーが発生する場合があるので、以下のコマンドを実行しておき、防止します。
$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
Vagrantの中で、Dockerを起動します。以下のコマンドは、プロジェクトディレクトリにdocker-compose.ymlが存在している場合の例です。
$ 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のパフォーマンスは、開発効率にかなりの悪影響を及ぼすレベルです。開発を進める前に、改善することをおすすめします。
参考
- https://qiita.com/necocoa/items/bd62ed3dba14b17552f2
- https://qiita.com/yn-misaki/items/c850a07f7858437e4d26