Vagrant上でrailsが重い!
synced_folderをデフォルトのままだとやったら重い!遅い!
これよくある問題らしい。ググったらたくさん出てきた。
解決策としてよく上がってるのがnfsを使う例
config.vm.synced_folder ".", "/vagrant", type: "nfs"
こんなやつですね。
これでも十分なのですが僕のプロジェクトだとnfsにするとコケるタスクが出てきました。
調べてみたら権限周りやらなんやらでよろしくないことが多いとか。
先輩エンジニアはrsyncとlsyncdでローカルで立ち上げてるrailsとvagrantで立ち上げてるrailsをsyncさせる荒業をやっていましたが初期起動が面倒だったので調べてみたところ
Vagrant 1.5 で追加された Rsync Synced Folder が良い
こんなの発見
てわけで試してみました。
Vagrant rsync使ってみる
前書き長くなったのでざっくりVagrantfileを晒します
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.define 'rails' do |rails|
rails.vm.box = 'rails'
rails.vbguest.auto_update = false
rails.vm.network :private_network, ip: "192.168.33.10"
rails.vm.network :forwarded_port, guest: 3306, host: 3306
rails.vm.network :forwarded_port, guest: 3000, host: 3000
rails.vm.synced_folder "rails", "/home/vagrant/synced_folder",
type: "rsync",
owner: "vagrant",
group: "vagrant",
rsync__exclude: [".git/", "tmp/", "public/uploads/", "public/assets/", "log/"]
end
config.vm.define 'es' do |es|
es.vm.box = 'elasticsearch'
es.vbguest.auto_update = false
es.vm.network :private_network, ip: "192.168.33.11"
es.vm.synced_folder "es", "/home/vagrant/synced_folder"
end
end
僕はプロジェクトで勝手にローカル環境いじったりしてるのでVagrantfileはgit管理していません。
この例ではboxもう一個用意してelastic search使ってみてます。
なので設定はよしなに変えてください
ちなみに僕のディレクトリ的は
sample-project
├── Vagrantfile
├── sample.sublime-project
├── es
│ └── 共有したかったやーつ
└── rails
├── app
├── config
├── data
├── db
├── doc
├── lib
├── log
├── public
├── script
├── spec
├── tmp
└── vendor
てな感じです。
rails.vm.synced_folder "rails", "/home/vagrant/synced_folder",
type: "rsync",
owner: "vagrant",
group: "vagrant",
rsync__exclude: [".git/", "tmp/", "public/uploads/", "public/assets/", "log/"]
今回の記事で大事なのはここだけです。
rsync__exclude
に同期してほしくないファイルを書いていきます。
僕は動的に生成されそうなやつ全部入れてみました。
rsyncなので基本的にhost->guestへの一方通行です。
動的に生成されるものも同期しちゃうとhostの状態を正として上書きしちゃうのできっとこんな感じになるかと思います。
たぶんプロジェクトにVagrantfileが入ってるなら.vagrantとかもexcludeに追加したほうがいいかもです(しなくても害はなさそうだけど)
んでvagrant upしたらいい感じに同期されます。
vagrant上で rails s
して見てlogがいないとか既に過去にrails動かしててuploads反映させたいとかあればいい感じに一度guestマシンに転送しておいてくださいな。
ちなみにbundle installは僕はhostでやってます。
guestでやりたければvendor/bundlerとかもexcludeに入れてやってください。
rsyncをwatchする
デフォルトやnfsのときと違い勝手には同期されません。
vagrant rsync-auto
ってコマンドが用意されています。
ただこいつたまにボケてて変更しても実行するまで遅かったりするので僕はsublime textから vagrant rsync
を叩いています。
sublime textのbuild systemにvagrant rsyncを登録する
僕はプロジェクトをsublime-projectに登録しているのでそいつにbuild systemを追加します。
{
"folders":
[
{
"path": "rails",
"folder_exclude_patterns": [".bundle", "log", "node_modules", "tmp", "vendor"]
}
],
"settings":
{
},
"build_systems": [
{
"name": "vagrant rsync",
"working_dir": "${project_path}",
"cmd": "vagrant rsync",
"shell": true
}
]
}
これでこのプロジェクトを開いてるときには
Tools
-> Build System
に vagrant rsync
がいるはず
こいつを選択しておくと ⌘ + b
で同期が実行するはず。
sublimeのconsoleにfinishedが表示されるので完了したかどうかも一目でわかります。
セーブしたら自動でvagrant rsync
毎回ビルド実行するのが面倒な方は自動化しましょう。
SublimeOnSaveBuild
というsublimeのプラグインをインストール
{
"filename_filter": "\\.(css|js|sass|less|scss)$",
"build_on_save": 1
}
これがデフォルトの設定ファイルらしいので先ほどのプロジェクトの設定ファイルをこんな風に変更
{
"folders":
[
{
"path": "rails",
"folder_exclude_patterns": [".bundle", "log", "node_modules", "tmp", "vendor"]
}
],
"settings":
{
"filename_filter": "\\.(css|js|sass|less|scss|slim|rb|coffee)$",
"build_on_save": 1
},
"build_systems": [
{
"name": "vagrant rsync",
"working_dir": "${project_path}",
"cmd": "vagrant rsync",
"shell": true
}
]
}
ymlやらhamlやら追加したければお好きな様にどうぞ。
基本これで変更があれば同期されるし、gulpやらと併用してたら気が向いたときに ⌘ + b
でbuildしてます。
まとめ
とりあえずsynced_folderのtypeをrsyncに変更してrsync-autoで監視ってのがなかなか良さ気でした。
僕の設定が悪いのかrsync-autoが微妙なときがあったのでsublimeからrsyncコマンド叩くようにしてみました。
rails自体も早くなった気配(気のせいかも)
とりあえず今は快適です。