docker-syncで自分もチームも幸せになれた話。

Docker

今年の年始から日本に帰ってきてフリーランスをしていくなかで、ありがたいことに現在までで3社4案件携わせてもらった中で、docker for macで構築された開発環境が激重なことが多かったので、短気な私はこれを解決しなくては気がすまなかった。

今回は、docker-syncを使ってローカル開発環境を激速にしたことで、皆が幸せになたのでそれをシェアしようと思う。

まずは結果から

こちらがDocker Syncを使わない時のAPIリクエスの速度。

最大5秒弱の時間がかかってます。

そして続いてDocker Syncを使ったパターン。

同じAPIが1秒台を記録しております。

下準備

まずはローカルにdocker-syncの本体をインストールしちゃいましょう。

$ gem install docker-sync
$ brew install fswatch

続いて、ホスト<=>コンテナを同期するためにunisonをインストール。

$ brew install unison

これで準備は完了。

docker-sync.ymlを作ろう

version: '2'

syncs:
  sync:
    sync_strategy: 'native_osx'
    src: './'
    sync_excludes: ['.git', '.github', '.idea', '.gitignore', '.DS_Store']
    host_disk_mount_mode: 'consistent' 

docker for macを使ってるなら、sync_strategyはnative_osxを使えばOK。

srcは同期対象のローカルパスです。

私は、同期対象パスのカレントにdocker-sync.ymlを作成したので、'./'となてます。

sync_excludesは同期から外したいファイルを指定します。

不要なものを除外しておきましょう。

最後に、host_disk_mount_modeですが、私は同期に矛盾が発生するのが嫌なのでconsistentを指定しました。

これら詳しい設定を知りたい場合は公式ドキュメントをご覧ください。

docker sync 公式ドキュメント

ymlファイルを書き終えたら次のコマンドでsyncコンテナを起動します。

docker-sync start

続いてdocker-compose.ymlを書き換える

自分の場合はlaravelなのでphp fpmコンテナをsyncコンテナ経由で同期するように設定します。

以下私の例です。

まずdocker-syncを使用せず通常のdocker-compose.ymlはこんな感じになってると思います。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
    laravel:
      image: laravel:latest
      build:
        context: .
        args:
          - "BUILD_ARGUMENT_ENV=dev"
          - "BUILD_ARGUMENT_DEBUG_ENABLED=false"
        dockerfile: ./Dockerfile
      container_name: laravel
      expose:
        - "9000"
      volumes:
        - .:/var/www/html
      depends_on:
        - mongodb
        - redis
      links:
        - mongodb
        - redis
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
volumes:
  dbdata:
  redis-data:

volumesのところが

 - .:/var/www/html

となっており、docker-compose.ymlと同じ場所にあるローカルの階層をコンテナ内部の/var/www/htmlにマウントする指定がしてあります。

続いてdocker-syncを使う場合の変更。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
    laravel:
      image: laravel:latest
      build:
        context: .
        args:
          - "BUILD_ARGUMENT_ENV=dev"
          - "BUILD_ARGUMENT_DEBUG_ENABLED=false"
        dockerfile: ./Dockerfile
      container_name: laravel
      expose:
        - "9000"
      volumes:
        - sycn:/var/www/html #ここをsyncコンテナを経由するよう書き換え。
      depends_on:
        - mongodb
        - redis
      links:
        - mongodb
        - redis
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
volumes:
  dbdata:
  redis-data:
  sync: #追記
    external: true

先程のdocker-sync.ymlで立ち上げたsyncコンテナを経由するように書き換えています。

ちなみにsyncコンテナの名称は、docker-sync.ymlで指定しています。

version: '2'

syncs:
  sync: #ここで指定している任意の名前。
    sync_strategy: 'native_osx'
    src: './'
    sync_excludes: ['.git', '.github', '.idea', '.gitignore', '.DS_Store']
    host_disk_mount_mode: 'consistent' 

Makefileでコマンドをまとめよう

最後に、Makefileを作成してコマンドをまとめちゃいましょう。

Makefile

sync-start:
    @docker-sync start
    @docker-compose -f docker-compose.yml up -d
    @make exec cmd="chmod 777 -R /var/www/html/storage"
    @make exec cmd="chmod 777 -R /var/www/html/public"
    @make exec cmd="chmod -R 775 /var/www/html/bootstrap/cache"

sync-stop:
    @docker-sync stop
    @docker-compose -f docker-compose.sync.yml $(project) down

sync-restart:
    @docker-sync clean
    @docker-sync start

Makefileを使用するとこれら多くのコマンドをワンコマンドにまとめられます。

使用するときは

$ make sync-start

と打ち込めばMakefileで指定したコマンドが走ります。

まとめ

たったこれだけの手間で、ローカル開発環境におけるAPIリクエストが3倍から4倍程度早くなります。

開発はチームで行うものだから、こういうだれもが接する物事の時間短縮は人数×効率という数式が成立して、全体としてものすごい生産性を向上できる類です。

積極的に効率化して皆がノンストレスで生産性を上げられるようにしてききたい。

タイトルとURLをコピーしました