LoginSignup
4
3

More than 3 years have passed since last update.

マルチOS対応Docker開発環境の作り方【Mac対応編】

Last updated at Posted at 2019-12-11

この投稿は Magento Advent Calendar 2019 の11日目です。

皆さんDocker使ってますか?

以前はVirtualbox+Vagrantを使って開発環境を整えていたのですが、動きが遅い重い!
当時個人的に気になっていたDockerに(趣味半分で)乗り換えてみたところ、早い軽いで素晴らしいものでした。

私はもっぱらLinux(Ubuntu)をメインで使っているのですが、社内にはMacやWindowsを使っている開発者もいます。

せっかく作ったし他のOSでも使えるようにしよう、まずはMacで試してみよう!と思っていたところ、ある問題に阻まれてしまったのでした。

Docker for Macの欠点

Linuxで使っていたイメージや設定ファイルを移動させ、起動させるところまでは順調でした。
ですが…

明らかに動きが遅い……!!!

実はこの問題、Docker for Macでは有名で、以前私もこの問題を解決しようと悪戦苦闘していました。
Docker Meetup Kansai で発表したスライドがあるので、もし興味があればそちらもご覧ください。

Docker開発環境のMac対応に苦戦した話.jpg
Docker開発環境のMac対応に苦戦した話

このときは1/4程度しか改善されないという、早くはなったが実用的ではないという悲しい結果でした。

今回はその続きの話となります。

その後調べたところ、2つ効果があるかも知れない解決策を見つけることが出来ました。

NFS Sharing Volume

実は、dockerにはVolumeにNFSをマウントする機能があります。
ですが、Docker for Macの遅さはmacOSとLinuxコンテナのファイルシステムの違いが原因なので、NFS越しにマウントしたところで早くなるはず無いだろう…と思っていました。

ところが、

Docker for Mac でも快適な Symfony 開発環境を作りたい

こちらの記事によるとNFS Volumeを使うことでかなり改善されることが判明しました。
なぜ早くなるのかは謎ですが、効果があるかも知れないなら試すしかありません!

Macでnfsdを動かすには、/etc/nfs.conf/etc/exports を設定しておく必要があります。

/etc/nfs.conf
#
# nfs.conf: the NFS configuration file
#
nfs.server.mount.require_resv_port = 0
/etc/exports
/System/Volumes/Data/Users/{USERNAME}/{PASS_TO_PROJECTROOT} localhost -alldirs -mapall={uid}:{gid}

-mapall オプションで指定したUIDとGIDは、NFSでアクセスした際に指定したユーザーのものとして扱われます。

macOS Catalinaをお使いの方には注意点が二点あって、一つは /Users/{USERNAME} で始まるパスを指定してもエラーになってしまいます。
詳しくは以下の記事が参考になるかと思います。

macOS CatalinaからNFS exportsするには

もう一点は、DocumentsやDownloads、Desktop下を使う場合は明示的に権限を付与(?)しなくてはいけないようです。

Docker: the Problem with MacOS Catalina

以上が設定できれば sudo nfsd start で起動するとホスト側の設定は終了です。

docker-compose.ymlの方にもNFSを使う設定をします。

docker-compose.yml
version: "3"
services:
  nfs:
    image: ubuntu:18.04
    volumes:
      - src:/src:nocopy
volumes:
  src:
    driver: local
    driver_opts:
      type: nfs
      device: ":/System/Volumes/Data/Users/{USERNAME}/{PASS_TO_PROJECTROOT}"
      o: addr=host.docker.internal,rw,nolock,hard,nointr,nfsvers=3

services下のvolumesに :nocopy を忘れず、driver_optsのdeviceにexportsで指定したパスを書くことを忘れずに!
これでNFS Volumeを使ったコンテナが起動できます✌️

欠点を挙げるとするならば、プロジェクトごとにdocker-compose.ymlにパスを書く必要があって手間という点です。
Gitで管理していたりすると、誤Pushとかがありそうで怖いですよね…。

Docker-sync

もう一つは高速にホストとコンテナ間を同期するためのツール、docker-syncです。

http://docker-sync.io/

このツールは、ホストとコンテナ間でrsyncやunisonなどを使って高速な同期を実現しているようです。
rsyncの方が高速(?)のようですが同期が双方向ではなく一方通行(ホスト→コンテナ)なのがネックなので、今回はunisonを使ってみます。

brew install unison
brew install eugenmayer/dockersync/unox
gem install docker-sync

以上のコマンドでインストールが完了します。
詳しいインストール手順は公式ドキュメントをご覧ください。

docker-syncには docker-sync.yml が必要になります。

docker-sync.yml
version: "2"
syncs:
  src:
    src: '/{PASS_TO_PROJECTROOT}'
    sync_strategy: 'unison'
    sync_userid: '{UID}'
docker-compose.yml
version: "3"
services:
  nfs:
    image: ubuntu:18.04
    volumes:
      - src:/src
volumes:
  src:
    external: true

docker-sync.ymlとdocker-compose.yml間でVolume名を統一しないと正しく起動しないので注意が必要です。
設定ファイルが準備できたら、

docker-sync start

このコマンドで起動してあげると、Volumeを作成して同期が開始されるという仕組みになっています。
Docker-syncを起動した状態でdockerコンテナにVolumeをマウントすると、ホスト-コンテナ間が同期されている状態になる、といった具合です。

Docker-syncの欠点は別途インストールが必要な点と、このコマンドを打つ手間があるところでしょうか。
起動しっぱなしでも良いのかも知れませんが、使い終わったら終わらせておきたい気もしますよね…🤔

測定

time dd if=/dev/zero of=/benchmark bs=1k count=100000

このコマンドで100MBのファイルを作成する時間を計測するベンチマークを取ってみました。

結果は…

  • 通常のVolumeが約25秒
  • NFS Volumeが約2.5秒
  • Docker-syncが約0.35秒

と、Docker-syncの圧倒的勝利となりました!
NFS Volumeもかなりはやいのですが、Docker-syncはほぼネイティブと変わらない速度ですね。

まとめ

いかがだったでしょうか?(殴)

NFSでもかなり早くで感動したのですが、Docker-syncはさらに早くてこんなにも違うのかと驚きました。

ここまでMagento Adventcalendarっぽく無い内容でしたが、Magento2はプロジェクトのファイル数がどうしても多くなってしまうので、読み書きのスピードはとても大事になってきます。
今回のこの結果を踏まえて次回、どうマルチOSに対応したdocker-compose.ymlを書くといいのかを書いていこうかと思います。

次 → マルチOS対応Docker開発環境の作り方【docker-compose編】

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3