15
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

mutagenのsyncとdocker-composeを連携させて使う

Posted at

はじめに

最近Docker for MacのMutagen-based cachingを使うという記事が話題になっていたが、mutagen単体でDockerコンテナと連携するやり方が英語の記事を含めてもなかなか見つけられなかったのでまとめておく。

なお、本記事の方法ではMutagen-based cachengは利用しないため、Dockerはstable版のままでよい(上記記事の設定は試していないため動作の違い等は不明)。

またここで扱っているのはmutagenのsyncforwardについてはこちらの記事に載っている。

環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.14.6
BuildVersion:   18G5033
$ docker -v
Docker version 19.03.8, build afacb8b
$ docker-compose -v
docker-compose version 1.25.5, build 8a1c60f6

準備

1. インストール

公式に書いてある通り。投稿時のバージョンは0.11.4。

$ brew install mutagen-io/mutagen/mutagen
$ mutagen version
0.11.4

2. デーモン起動

$ mutagen daemon start

3. コンテナ起動

テスト用に用意したdocker-compose.ymlは以下。

docker-compose.yml
version: '3.7'
services:
  web:
    image: php:7.4-apache
    container_name: web
    ports:
      - 80:80
  db:
    image: mysql:8.0
    container_name: db
    environment:
      MYSQL_ROOT_PASSWORD: root
$ docker-compose up -d

手動で使う

1. セッションの作成

$ mutagen sync create --name=mutagen-test --default-file-mode-beta=644 . docker://web/var/www/html

こちらのコマンドでmutagen-testという名前でカレントディレクトリ(alpha)の内容をwebコンテナの/var/www/html(beta)と同期するセッションを作成できる。なぜsourcedestではなくalphabetaなのかと疑問だったが、mutagenは双方向に同期できるためのようだ
--default-file-mode-beta=644はbeta(コンテナ)側のファイルパーミッションを644にする設定。mutagenのデフォルトではパーミッションがディレクトリ700、ファイル600になる(参考)ので、ここで指定して(もしくは--default-owner-beta=www-dataとして)おかないと、今回のようにapacheから参照したい場合にパーミッションエラーになる。

セッションを作成した時点で同期が始まる。これまで使っていてファイルが消えたりしたことはないが、万が一に備えてバージョン管理されている状態で行った方がよい。

2. 同期の状況の確認

  • 実行時点
$ mutagen sync list
--------------------------------------------------------------------------------
Name: mutage-test
Identifier: sync_pPfc22rlD8RcEDldZ9CbMTJzTnRszZHfokhkZtopw7a
Alpha:
        URL: /tmp/mutagen
        Connection state: Connected
Beta:
        URL: docker://web/var/www/html
                DOCKER_HOST=
                DOCKER_TLS_VERIFY=
                DOCKER_CERT_PATH=
        Connection state: Connected
Status: Watching for changes
  • リアルタイム
$ mutagen sync monitor
Name: mutagen-test
Identifier: sync_pPfc22rlD8RcEDldZ9CbMTJzTnRszZHfokhkZtopw7a
Labels: None
Alpha: /tmp/mutagen
Beta: docker://web/var/www/html
        DOCKER_HOST=
        DOCKER_TLS_VERIFY=
        DOCKER_CERT_PATH=
Status: Watching for changes                                                    

セッション作成直後の最初の同期中にmonitorを見ているとStatus: Staging files on beta: 41% (9191/22567)などといった状態になり、これがStatus: Watching for changesになったら同期完了。
ファイルの量やマシンスペックにもよると思われるが、上記の22567ファイルの規模(今回のものとは別のプロジェクト)で20秒程度だった。monitorは同期が完了しても勝手には終わらないので^Cで抜ける。

3. 動作確認

  • 新規作成
$ ls
docker-compose.yml
$ echo '<?php echo "It works!";' > index.php
$ docker-compose exec web ls -la
total 20
drwxrwxrwx 1 www-data www-data 4096 Jun  4 05:29 .
drwxr-xr-x 1 root     root     4096 May 15 12:41 ..
-rw-r--r-- 1 root     root      206 Jun  4 05:28 docker-compose.yml
-rw-r--r-- 1 root     root       24 Jun  4 05:29 index.php
$ curl localhost
It works!
  • 編集
$ echo '<?php echo "It works fine!";' > index.php
$ curl localhost
It works fine!

ちゃんと同期されているようだ。

今回はサイズも小さいので一瞬だが、実プロジェクトでは数秒のラグはある(コンテナでファイル自動生成などをしてすぐにホストでgit statusで見るとまだ反映されていなかったりする)。

4. セッションの終了

$ mutagen sync terminate mutagen-test
$ mutagen sync list
Error: no matching sessions exist

5. 手動の問題点

最初はこれでしばらく使っていたが、例えばセッション実行中にコンテナを落とすと、Status: [Errored] Connecting to betaとなり同期エラーになったり、そこからdocker-compose up -dで再度コンテナを起動しても、Status: Halted due to one-sided root emptyingとなって同期はできずセッションを作り直さなければならないという問題があった。

先述のオーナーやパーミッションは設定ファイルに書くこともできるが、コンテナとの連携も合わせて一括管理したいなあと思っていたところ、次のmutagen projectを使う方法を見つけた。

mutagen projectを使う

mutagenにはprojectという機能があり、セッションの作成や終了といったライフサイクルと任意のコマンドを組み合わせて設定ファイルで管理し実行できる。

公式のexamplesがわかりやすい。

今回は簡略化した以下のmutagen.ymlを使用する。

mutagen.yml
beforeCreate:
  - docker-compose up -d

afterTerminate:
  - docker-compose down

sync:
  defaults:
    ignore:
      vcs: true
  mutage-test:
    alpha: "."
    beta: "docker://web/var/www/html"
    mode: "two-way-resolved"
    configurationAlpha:
      permissions:
        defaultFileMode: 644
        defaultDirectoryMode: 755
    configurationBeta:
      permissions:
        defaultOwner: www-data
        defaultGroup: www-data
        defaultFileMode: 644
        defaultDirectoryMode: 755

beforeCreateでセッション作成前にコンテナを起動、afterTerminateでセッション終了後にコンテナも終了する。

また、syncの項目にセッションの設定を書いておける。
ここではalphaのパーミッションも設定しているが、これはフレームワークなどのファイル自動生成やcomposerやnpmでのライブラリのインストールをコンテナ上で行った場合に700600でホストに同期されるのを防ぐためである。

公式ではafterCreateで同期完了までのwaitを入れている。同期が速いといっても多少のラグはあるので、実プロジェクトで採用する際は真似しておくと、同期完了前にアクセスしてファイルが見つからないなどのエラーを避けられる。

docker-compose.ymlと同階層に置いてバージョン管理しておく。

1. セッションの開始

$ mutagen project start
Started Mutagen daemon in background (terminate with "mutagen daemon stop")
> docker-compose up -d
Creating network "mutagen_default" with the default driver
Creating web ... done
Creating db  ... done
Created session sync_3bwd2dlhwaFrNNeUNRe4WYegNxOdPjEj3swQ8Xx1Hz6

セッション開始前にコンテナが起動しているのが確認できる。デーモンが起動していなかった場合はそっちも起動してくれて便利。

セッション実行中はmutagen.yml.lockというファイルができるので.gitignoreに追加しておくとよい。

2. セッションの終了

$ mutagen project terminate
> docker-compose down
Stopping web ... done
Stopping db  ... done
Removing web ... done
Removing db  ... done
Removing network mutagen_default

3. コマンドの実行

また、composerやnpmなどのscriptsと同様に任意のコマンドを定義できるようになっている。以下を設定ファイルに追加する。

mutagen.yml
commands:
  repl: docker-compose exec web php -a
  db: docker-compose exec db mysql -uroot -p
$ mutagen project start # セッションを終了していない場合は不要
$ mutagen project run repl
Interactive shell

php > echo 'hello';
hello
php > ^D
$ mutagen project run db
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.20 MySQL Community Server - GPL

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

おわりに

mutagen projectを利用することで、mutagenとdocker-composeを連携できて便利だった。
現状そこまで不満もないのでDockerのMutagen-based cachingがstableになるまではこの方法を使おうと思う。

参考

15
13
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
15
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?