はじめに
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を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-backやrsync-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/"]