LoginSignup
22
18

More than 5 years have passed since last update.

Vagrant rsync + Railsでコードの変更が反映されない件

Posted at

問題

Vagrantの共有フォルダでVM上とコードをrsync経由で同期させているとき、なぜかローカルで編集した変更がVM上のRailsサーバーに反映されないことがある。Railsサーバーを再起動すれば、ちゃんと反映される。

原因

VM上の変更したファイルのmtimeが更新されていないため、Railsのautoloadが実行されなかった。

RailsのautoloadはActiveSupport::FileUpdateCheckerを使って以下のようにファイルのmtimeを見て変更されたかどうかを判定している。

lib/active_support/file_update_checker.rb
def updated?
  current_watched = watched
  if @last_watched.size != current_watched.size
    @watched = current_watched
    true
  else
    current_updated_at = updated_at(current_watched)
    if @last_update_at < current_updated_at
      @watched    = current_watched
      @updated_at = current_updated_at
      true
    else
      false
    end
  end
end

# ...

def updated_at(paths)
  @updated_at || max_mtime(paths) || Time.at(0)
end

# ...

def max_mtime(paths)
  time_now = Time.now
  paths.map {|path| File.mtime(path)}.reject {|mtime| time_now < mtime}.max
end

変更したファイルのmtimeをローカルとVMで比べてみると、下のようになった。

local
$ stat -x app/controllers/accounts_controller.rb
  File: "app/controllers/accounts_controller.rb"
  Size: 117          FileType: Regular File
  Mode: (0644/-rw-r--r--)         Uid: (  501/   naoty)  Gid: (   20/   staff)
Device: 1,4   Inode: 17448444    Links: 1
Access: Wed Oct  7 23:17:24 2015
Modify: Wed Oct  7 23:17:21 2015
Change: Wed Oct  7 23:17:21 2015
vm
$ stat app/controllers/accounts_controller.rb
  File: `app/controllers/accounts_controller.rb'
  Size: 117             Blocks: 8          IO Block: 4096   通常ファイル
Device: fd00h/64768d    Inode: 2331313     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/ vagrant)   Gid: ( 1000/ vagrant)
Context: unconfined_u:object_r:default_t:s0
Access: 2015-10-06 17:47:42.590929945 +0000
Modify: 2015-10-07 14:17:21.000000000 +0000
Change: 2015-10-06 17:47:43.386929905 +0000

確かにVM上のmtimeはぜんぜん更新されてない…。

解決

rsyncの--timesオプションをVagrantのrsyncオプションに渡すことで、ファイルのmtimeも転送されるようにする。

Vagrantfile
config.vm.synced_folder ".", "/vagrant", type: "rsync",
  rsync__args: %w(--verbose --archive --delete -z --copy-links --times),
  rsync__exclude: %w(.git/ log/ tmp/ vendor/)

rsync__argsrsyncに渡す引数を指定できる。ここでは、デフォルトで渡される引数に加えて--timesオプションを指定している。

22
18
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
22
18