Vagrantのrsync時に、Host側に無いFileがVM側から削除されるのを回避する方法

  • 13
    Like
  • 0
    Comment
More than 1 year has passed since last update.

はじめに

Client系の開発環境を構築しようとVagrantを使ったのですが、Vagrantのrsyncでややハマッた時ので、その解決策をチラ裏しておきます。

やろうとしたこと

Vagrantを使って下記図みたいなWorkflowで開発をしようと思っていました。

  • Host/VMの双方で、gitから最新のcodeを取得
  • VM上でのみnmp/bower installで、必要なmoduleをinstall
  • Host上で好きな開発Toolでjsを編集
  • Vagrantのrsyncの機能で、編集したjs fileをVM側にcopy
  • VM上でgulp watchでfile更新を検出し、appがrestart

vagrant-rsync.jpg

ところが、VagrantのrsyncをDefault設定のまま使おうとすると、このようには動きませんよ、と言うお話です。

ハマるポイント

Vagrantのrsync機能は、Defaultでは Host側のFolderの内容とVM側のFolder内容を完全に合わせようとします。ここでのポイントは、VM側のFolderには存在するが、Host側のFolderに存在しないFile達は、rsyncの瞬間VM側で削除される、と言う事です。

そのため、VM側でnpm install等を行い、node_moduleをシコシコinstallしても、Host側で同じfileを用意しておかない限り、rsyncを発動した瞬間に(VM側に無いfileは)VM側から削除されます。当然その状態でVM上でappは動きません。

原因と回避方法

この振る舞いの原因は、公式Documentにもありますが、VagrantのrsyncのDefaultの引数が["--verbose", "--archive", "--delete", "-z", "--copy-links"].になっているからです。

rsyncの引数を見ると解りますが、--deleteがあると、転送元に存在しないファイルはsync時に削除されます。

と言う事で、Vagrantfileに以下の様に書くと、

  • Host側に無いFileでもVM側から削除されない
  • Host側の更新されたFileがVM側にCopyされる

と言う風にマイルドに動いてくれます。rsync__argsでrsyncの引数を変えているのがポイントです。

config.vm.synced_folder "./shared", "/home/vagrant/shared", type: "rsync", rsync__args: ["--verbose", "--archive", "--compress"], rsync__exclude: ["./shared/.git/"]

これで、vagrant sshでVM側に入ってgulp watchしつつ、Host OS側でvagrant rsync-autoを実行した状態にしておくと、Host側で好きなIDE/Editorでjs fileを編集し、その変更が自動でVM側にも反映され、gulp watchでlivereloadされる、というworkflowが実現できます。

その他Vagrantでハマッた箇所

共有folder について

synced_folderで、(rsyncではなく)Host/VM間で共有folderとして設定する場合、3つほど注意点があります。

  • 共有したfolder配下で、(VM側には存在するが)Host側には存在しないFile達は、VM起動時に消されます
  • HostがWindows, VMがLinuxだと、共有したfolder配下のLinuxのsymbolic linkが動かない事があります
  • folder共有はとてもPerformanceが遅いです

自分はSymbolic Linkでハマりました。

rsyncはHost→VMでfileをsyncしますが、VM→Hostでfileをsyncしたい場合には、rsync-backrsync-pullと言ったpluginもあります。

network設定 について

Vagrantのnetwork設定は、この記事がとても詳しいですが、大きく以下の3つがあります。port forwardingだと、Host側のFirewall, Virus Soft等の設定に影響されるので注意です。

  • private network
    • VMはHostからのみAccess可能です
  • port forwarding
    • VMは、Host上ではあるPortをListenしているWeb appとしてAccess可能です
    • 外部からVMにAccessするには、外部からHost上のそのPortにAccessをする必要がありますが、Host側のFirewall/Virus Soft等のPort設定を正しく行う必要があります
  • public network
    • VMは、Network的にはHostとは別のDeviceに見えます。Host側のFirewall/Virus Softの影響は受けません

自分は最初、port forwardingにしてハマりました。

Syncが遅い

Syncの対象folderのfile数が多いと、Syncに時間がかかります。特にnode_modules以下は大量にfileがあるので、ここをSync対象に含めるととたんにSyncに時間がかかります(私の環境だと1分-2分かかります(泣))。そんなときは、rsync__excludeにnode_modulesを含めて上げてください、きっと捗るようになります。

config.vm.synced_folder "./shared", "/home/vagrant/shared", type: "rsync", rsync__args: ["--verbose", "--archive", "--compress"], rsync__exclude: ["./shared/.git/", "./shared/your-project/node_modules/"]