【Vagrantドキュメント意訳】11.同期フォルダ

# はじめに

本文章は、Vagrant公式サイト内のドキュメント内の[SYNCED FOLDERS](https://www.vagrantup.com/docs/synced-folders/)に記載されている内容を意訳に近い形で日本語化したものである。
誤訳が含まれている可能性が十分にあることを踏まえて、参考いただきたい。

# 同期フォルダ

同期フォルダはVagrantにホスト・マシン上のフォルダとゲスト・マシンとの同期を可能にさせる。それは、ホスト・マシン上のプロジェクトのファイルに対する作業を、プロジェクトをコンパイルや実行するゲスト・マシン内のリソースを使って続けることを可能とする。

デフォルトでは、Vagrantは/vagrantにプロジェクト・ディレクトリ([Vagrantfile](https://www.vagrantup.com/docs/vagrantfile/)があるディレクトリ)を共有する。

[基本的な使い方](https://www.vagrantup.com/docs/synced-folders/basic_usage.html)で同期フォルダの始め方を示す。

# 基本的な使い方

## 設定

同期フォルダは、Vagrantfile内で`config.vm.synced_folder`メソッドを使用することで設定する。設定方法は非常に単純である。

```bash
Vagrant.configure("2") do |config|
  # other config here

  config.vm.synced_folder "src/", "/srv/website"
end
```

はじめの引数はホスト・マシン上のディレクトリへのパスである。もし、パスが相対パスであれば、プロジェクト・ルートからの相対パスとなる。2つ目のパラメータは、ゲスト・マシンで共有するフォルダの位置を示す絶対パスである。このフォルダがもし存在しない場合、（必要に応じて再帰的に）生成される。

## オプション

同期フォルダを設定する際に、追加的なオプション引数を指定することもできる。これらのオプションを以下に示す。これらのオプションのより詳細な使用例については後述する。owner/groupの例では2つの追加的なオプションがコンマによって区切られている点に注意すること。

これらのオプションに加えて、ある同期フォルダの種類ではより多くのオプションが許されているかもしれない。この詳細については、その同期フォルダの種類に対するドキュメントを参照すること。組み込まれている同期フォルダの種類は、これらの文書に対するナビゲーション内のほかのページで見つけることができる。

* [`create`](https://www.vagrantup.com/docs/synced-folders/basic_usage.html#create) (ブール値) - trueの場合、存在しなければホストのパスを生成する。デフォルトではfalseである。
* [`disabled`](https://www.vagrantup.com/docs/synced-folders/basic_usage.html#disabled) (ブール値) - trueの場合、この同期フォルダは無効かつ設定されない。これは以前に定義した同期フォルダを無効にしたり、そのほかの要因に基づいた、条件付きで定義を無効にしたりする場合に使用することができる。 
* [`group`](https://www.vagrantup.com/docs/synced-folders/basic_usage.html#group) (文字列) - 同期フォルダの属するグループ。デフォルトではこれはSSHユーザである。いくつかの同期フォルダの種類ではグループの変更はサポートしていない。
* [`mount_options`](https://www.vagrantup.com/docs/synced-folders/basic_usage.html#mount_options) (列挙) - `mount`コマンドに対して受け渡すための追加的なマウントオプションのリスト。
* [`owner`](https://www.vagrantup.com/docs/synced-folders/basic_usage.html#owner) (文字列) - その同期フォルダのオーナーとなるユーザ名。デフォルトではSSHユーザとなる。いくつかの同期フォルダの種類ではオーナーの変更はサポートしていない。
* [`type`](https://www.vagrantup.com/docs/synced-folders/basic_usage.html#type) (文字列) - 同期フォルダの種類。これが指定されていなければ、Vagrantはその環境に対して最も適切な同期フォルダオプションを自動的に選択するが、"nfs"のように種類を指定することができる。

## 有効化

同期フォルダは`vagrant up`や`vagrant reload`の間で自動的に設定される。

## 無効化

同期フォルダは、その定義に対して`disabled`オプションを追加することで無効化できる。

```bash
Vagrant.configure("2") do |config|
  config.vm.synced_folder "src/", "/srv/website", disabled: true
end
```

デフォルトの`/vagrant`共有の無効化のやり方は以下のとおりである。

```bash
config.vm.synced_folder ".", "/vagrant", disabled: true
```

## オーナーとグループの変更

デフォルトではVagrantは同期フォルダをowner/groupをSSHユーザとして設定し、マウントする。異なったownerとgroupでフォルダをマウントするほうが望ましいことがよくある。それは以下に示すオプションによって設定する。

```bash
config.vm.synced_folder "src/", "/srv/website",
  owner: "root", group: "root"
```

## シンボリック・リンク

同期フォルダの実装とホスト/ゲストの組み合わせとの間のシンボリック・リンクのサポートについては一貫していない。Vagrantは、さまざまなハイパーバイザ(VirtualBoxなど)を設定することによって最も適切なシンボリック・リンクを生成するが、いくつかのホスト/ゲストの組み合わせは、まだ適切に動作しない。これは、シンボリック・リンクに依存するいくつかの開発環境に影響を及ぼす。

推奨することとしては、もしこれが重要であるならば、すべてのホスト/ゲストの組み合わせにおける同期フォルダとシンボリック・リンクをテストしておくことである。

# NFS

いくつかのケースにおいて、デフォルトの共有フォルダの実装(VirtualBox共有フォルダなど)は、高いパフォーマンス上の不利益がある。もし、同期フォルダに対して理想とするパフォーマンス以下しか得られないのであれば、[NFS](https://en.wikipedia.org/wiki/Network_File_System_%28protocol%29) は解決策を与えることができる。Vagrantにはホスト上とゲスト上でNFSサーバの設定を統合化するための、組み込まれたサポートがある。

> *Windowsユーザへ：* NFSフォルダはWindowsホスト上では動作しない。VagrantはWindows上でのNFS同期フォルダの要求は拒否する。

## 必要条件

NFSによる同期フォルダを使用する前に、ホスト・マシンにNFSサーバ・デーモンである`nfsd`がインストールされている必要がある。これは、Mac OS Xではプリ・インストールされており、Linuxでも通常、簡単もパッケージでインストールできる。

さらに、ゲスト・マシンはNFSサポートがインストールされている必要がある。これも、簡単なパッケージによるインストール方法がたいてい用意されている。

VirtualBoxプロバイダを使用しているなら、[プライベート・ネットワークの設定](https://www.vagrantup.com/docs/networking/private_network.html)が適切に行われているか確認する必要がある。これは、VirtualBoxの組み込みネットワークの制限のために必要である。VMWareにおいては必要ない。

## NFS同期フォルダの有効化

NFSを有効化するには、同期フォルダへ`type: "nfs"`フラグを追加するだけである。

```bash
Vagrant.configure("2") do |config|
  # ...

  config.vm.synced_folder ".", "/vagrant", type: "nfs"
end
```

もし、稼働しているゲスト・マシンのVagrantfileへ追加したのなら、変更を反映する為に`vagrant reload`を行う。

## NFS同期フォルダのオプション

NFS同期フォルダはNFS特有の指定可能なオプションを持っている。これらを以下に示す。これらのオプションは`type`オプションとともに、`config.vm.synced_folder`定義の最後の部分で指定することができる。

* [`nfs_export`](https://www.vagrantup.com/docs/synced-folders/nfs.html#nfs_export) (ブール値) - falseの場合、Vagrantは`/etc/exports`を勝手に変更せず、すでにそうしたものであると仮定する。
* [`nfs_udp`](https://www.vagrantup.com/docs/synced-folders/nfs.html#nfs_udp) (ブール値) - 転送にUDPを使用するかどうかを指定する。UDPは高速であるが、いくつかの制限事項がある(詳細はNFSのドキュメントを参照のこと）。デフォルトではtrueである。
* [`nfs_version`](https://www.vagrantup.com/docs/synced-folders/nfs.html#nfs_version) (文字列 | 整数値) - ゲスト上でマウントする際に使用するためのNFSのプロトコル・バージョン。デフォルトでは 3 である。

## NFSグローバル・オプション

Vagrantfile内の`config.nfs`で設定可能なグローバルなNFSのオプションがさらに存在する。これらを以下に示す。

* [`functional`](https://www.vagrantup.com/docs/synced-folders/nfs.html#functional) (ブール値) - デフォルトではtrue。もしfalseの場合、NFSは同期フォルダの種類として使用されない。同期フォルダにおいて明示的にNFSが要求されていた場合、これはエラーとなる。
* [`map_uid`](https://www.vagrantup.com/docs/synced-folders/nfs.html#map_uid) と `map_gid` (整数値) - すべてのread/wrteの要求にそれぞれ対応付けるためのUID/GID。 これはゲスト・マシン自身のowner/groupに影響を与えることはないが、どのような記載も、ホスト上でこのUID/GIDとして記載されたかのように振る舞う。これはVagrantを実行しているカレント・ユーザに対してデフォルトとなる。
* [`verify_installed`](https://www.vagrantup.com/docs/synced-folders/nfs.html#verify_installed) (ブール値) - デフォルトはtrueである。これがfalseの場合、VagrantはNFSがインストールされているかどうかを確認しない。

## NFS引数の指定

上記で示したオプションに加えて、`mount_options`キーを使用することでNFS共有をマウントした際のNFS引数の変更を指定する事ができる。例えば、クライアント・マウント・オプションとして`actimeo=2`を使用する場合を示す。

```bash
config.vm.synced_folder ".", "/vagrant",
    :nfs => true,
    :mount_options => ['actimeo=2']
```

これは、以下に示すゲスト上で実行されたマウントコマンドの結果と一致する。

```bash
mount -o 'actimeo=2' 172.28.128.1:'/path/to/vagrantfile' /vagrant
```

マウントが追加された際に`/etc/exports`テンプレート内で、OS特有の`linux__nfs_options`キーや`bsd__nfs_options`キーを使用して、指定された引数を調整することができる。これらのオプションはVagrantによって追加されたデフォルトの引数を完全に上書きする点に注意すること。例えば、NFS共有を非同期にするには以下のようにする。

```bash
config.vm.synced_folder ".", "/vagrant",
    :nfs => true,
    :linux__nfs_options => ['rw','no_subtree_check','all_squash','async']
```

これは、ホスト上の`/etc/exports`の内容に従った結果と一致する（`async`フラグが追加されている点に注意すること）。

```bash
# VAGRANT-BEGIN: 21171 5b8f0135-9e73-4166-9bfd-ac43d5f14261
"/path/to/vagrantfile" 172.28.128.5(rw,no_subtree_check,all_squash,async,anonuid=21171,anongid=660,fsid=3382034405)
# VAGRANT-END: 21171 5b8f0135-9e73-4166-9bfd-ac43d5f14261
```

## Root特権要求

NFSを設定する為に、Vagrantはホスト上のシステム・ファイルを変更する必要がある。そのため、`vagrant up`の間に管理者権限にを要求されることがある(一般的には`sudo`プログラムによって）。これらの権限はNFSサーバを開始したり停止できるよう`/etc/exports`を変更するために使用される。

`vagrant up`の度にパスワードを打ち込みたくないのであれば、Varantはパスワードを入力する手間を省くために、パスワードを入力する手間を省けるようにきめ細かなsudoersの変更を可能とする、熟考して作り上げられたコマンドを使用する。

以下において、一組のsudoersのエントリをもつ。Vagrantが`/etc/exports`の変更を行う際にOS毎に違いがあるので、対象とするホスト上で少し変更する必要があるかもしれない点に注意すること。*nixユーザは、`visudo`を用いて`/etc/sudoers`ファイルを編集すること。それは、昇格した権限を得られなくなってしまうような文法誤りから守ってくれる。

以下のすべてのスニペットはVagrantの1.7.3以上を対象とする。

OS Xでは、sudoersはこのようなエントリを持つべきである。

```bash
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD = /sbin/nfsd restart
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /usr/bin/sed -E -e /*/ d -ibak /etc/exports
%admin ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD, VAGRANT_EXPORTS_REMOVE
```

Ubuntu Linuxでは、sudoersはこのようになるはずである。

```bash
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_EXPORTS_COPY = /bin/cp /tmp/exports /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /etc/init.d/nfs-kernel-server status
Cmnd_Alias VAGRANT_NFSD_START = /etc/init.d/nfs-kernel-server start
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /bin/sed -r -e * d -ibak /tmp/exports
%sudo ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE, VAGRANT_EXPORTS_COPY
```

Fedora Linuxでは、sudoersはこのようになるだろう（vagrantグループに所属するユーザを与えること）

```bash
Cmnd_Alias VAGRANT_EXPORTS_ADD = /usr/bin/tee -a /etc/exports
Cmnd_Alias VAGRANT_NFSD_CHECK = /usr/bin/systemctl status nfs-server.service
Cmnd_Alias VAGRANT_NFSD_START = /usr/bin/systemctl start nfs-server.service
Cmnd_Alias VAGRANT_NFSD_APPLY = /usr/sbin/exportfs -ar
Cmnd_Alias VAGRANT_EXPORTS_REMOVE = /bin/sed -r -e * d -ibak /tmp/exports
%vagrant ALL=(root) NOPASSWD: VAGRANT_EXPORTS_ADD, VAGRANT_NFSD_CHECK, VAGRANT_NFSD_START, VAGRANT_NFSD_APPLY, VAGRANT_EXPORTS_REMOVE
```

## その他の注意点

**暗号化フォルダ：**暗号化されたディスクがある場合、NFSは頻繁にファイルシステムのエクスポート拒否する。NFSによるエラー/メッセージはしばしば明確ではない。あるエラー/メッセージは`<path> does not support NFS`のようなものだ。暗号化されていないディレクトリを共有する以外に有効な回避策はないようだ。

# RSYNC

## 同期フォルダ種類：`rsync`

Vagrantは[rsync](https://en.wikipedia.org/wiki/Rsync)をゲストマシンとフォルダを同期するための機構として使用することが出来る。この同期フォルダの種類は、NFSやVirtualBox共有フォルダがゲスト・マシンで使用できないなど、その他の同期フォルダ機構が使用できない様な状況において、第一に有用である。

同期フォルダは、稼働しているマシンからVagrantによって起動されたマシンへの一時的、一方通行の同期を行う。

[rsync](https://www.vagrantup.com/docs/cli/rsync.html)と[rsync-auto](https://www.vagrantup.com/docs/cli/rsync-auto.html)コマンドはファイル・システムで変更が発生した際に、強制的に、自動的にresyncをするために使用することができる。 これらのコマンドを実行しなければ、Vagrantは`vagrant up`または`vagrant reload`を行った時だけsyncされる。

## 必要条件

rsync同期フォルダ種類を使用する為に、Vagrantが稼働しているマシンはパス上に`rsync`（または`rsync.exe`）が存在している必要がある。この実行可能ファイルは標準的なrsyncツールと同様の動作をすることが期待される。

Windowsにおいては、rsyncはCygwinまたはMinGWとともにインストールされ、Vagrantによって検出可能かつ適切に動作する必要がある。

目的のマシンにもrsyncがインストールされている必要があるが、Vagrantは多くのオペレーティング・システムにrsyncを自動的にインストールすることができる。もし、Vagrantがそのオペレーティング・システムにrsyncを自動的にインストールできなければ、教えてくれる。

目的のフォルダは、接続を開始したユーザとして生成され、これはデフォルトでは`vagrant`である。このユーザは目的のフォルダに対する適切な権限を持っている必要がある。

## オプション

rsync同期フォルダ種類は以下のオプションが適用できる。

* [`rsync__args`](https://www.vagrantup.com/docs/synced-folders/rsync.html#rsync_args) (文字列の列挙) - `rsync`に与えるための引数のリスト。デフォルトでは`["--verbose", "--archive", "--delete", "-z", "--copy-links"]`である。
* [`rsync__auto`](https://www.vagrantup.com/docs/synced-folders/rsync.html#rsync_auto) (ブール値) - falseである場合、`rsync-auto`は監視されず、自動的にこのフォルダを同期しない。デフォルトではtrueである。
* `rsync__chown` (ブール値) - falseである場合、同期フォルダに対する[`ownerとgroupの`](https://www.vagrantup.com/docs/synced-folders/basic_usage.html)オプションは拒否され、Vagrantは再帰的な`chown`を実行しない。デフォルトではtrueである。このオプションはchownがいくつかの開発環境に対して問題を引き起こすために存在する。いかなる所有権に対する`rsync__args`オプションも`rsync__chown`によって**上書きされる**。
* [`rsync__exclude`](https://www.vagrantup.com/docs/synced-folders/rsync.html#rsync_exclude) (文字列または文字列の列挙）- 同期から除外するファイルとディレクトリのリスト。この値はrsyncの除外パタンのいずれも適応できる。デフォルトでは、".vagrant/"ディレクトリが除外される。".git/"のようなリビジョン管理用のディレクトリは除外することを推奨する。
* [`rsync__rsync_path`](https://www.vagrantup.com/docs/synced-folders/rsync.html#rsync_rsync_path) (文字列) - rsyncがあり、実行されるリモート・ホスト上のパス。これはプラットフォーム特有であるが、多くのゲストに対してh"sudo rsync"がデフォルトとなる。
* [`rsync__verbose`](https://www.vagrantup.com/docs/synced-folders/rsync.html#rsync_verbose) (ブール値) - trueの場合、rsyncプロセスからの出力はコンソールへ反映される。rsyncの出力は当然`rsync__args`の影響を受ける。デフォルトではfalseである。

## 例

以下はフォルダを同期するためのRSyncの使用例である。

```bash
Vagrant.configure("2") do |config|
  config.vm.synced_folder ".", "/vagrant", type: "rsync",
    rsync__exclude: ".git/"
end
```

## 特定のフォルダへのRsync

`vagrant`ユーザが権限をもたない場所へのコピーを要求する場合、`"--rsync-path='sudo rsync'"`を使ってゲスト上でsudoとともにrsyncを実行する。

```bash
Vagrant.configure("2") do |config|
  config.vm.synced_folder "bin", "/usr/local/bin", type: "rsync",
    rsync__exclude: ".git/",
    rsync__args: ["--verbose", "--rsync-path='sudo rsync'", "--archive", "--delete", "-z"]
end
```

# SMB

## 同期フォルダ種類：`smb`

Vagrantは[SMB](https://en.wikipedia.org/wiki/Server_Message_Block)をホスト・マシンとVagrantマシンとの双方向の同期フォルダを生成するための機構として使用することができる。

SMBはWindowsマシンに組み込まれ、VirtualBox共有フォルダのようなそのほかの機構の代替として高いパフォーマンスを提供する。

> **Windowsのみ！** SMBは現在ホスト・マシンがWindowsである場合のみ、サポートしている。ゲスト・マシンはWindowsまたはLinuxとすることができる。

## 必要条件

SMB同期フォルダ種類を使用するためには、Vagrantが稼働しているマシンがPowerShellのバージョン3以降がインストールされているWindowsマシンであることが必要である。これに加えて、Vagrantを起動したコマンド・プロンプトが管理者権限を持っている必要がある。Vagrantはこれらを新しいネットワーク・フォルダ共有を生成する為の権限として要求する。

目的のマシンはSMBファイルシステムをマウントすることができる必要がある。Linuxにおいてはこれを行うパッケージは通常`smbfs`または`cifs`と呼ばれている。Vagrantは、オペレーティング・システムにこれを自動的にインストールする方法を知っている。

## オプション

SMB同期フォルダ種類は適応可能な様々なオプションを持っている。

* [`smb_host`](https://www.vagrantup.com/docs/synced-folders/smb.html#smb_host) (文字列) - SMBのマウントがあるホストのIP。これが指定されていない場合、Vagrantはこれを自動的に決定しようと試みる。
* [`smb_password`](https://www.vagrantup.com/docs/synced-folders/smb.html#smb_password) (文字列) - SMBのマウントをマウントするための認証に使用されるパスワード。これは`smb_username`によって指定されたユーザ名に対するパスワードである。これが指定されていない場合、Vagrantはプロンプトで入力を促す。Vagrantfileで直接パスワードがさらされてしまうので、これを設定しないことを強く推奨する。
* [`smb_username`](https://www.vagrantup.com/docs/synced-folders/smb.html#smb_username) (文字列) - SMBマウントをマウントするための認証に使用されるユーザ名であるが、フォルダがマウントされている先のアカウントのユーザ名ではない。これは通常Windowsのユーザ名となる。もし、ドメインに参加しているならば、`user@domain`のように指定する。このオプションが指定されていない場合、Vagrantはプロンプトで入力を促す。

## 例

フォルダを同期するためのSMBの使い方の例を以下に示す。

```bash
Vagrant.configure("2") do |config|
  config.vm.synced_folder ".", "/vagrant", type: "smb"
end
```

## アイドル切断の防止

Windowsにおいて一定期間の間ファイルがアクセスされなかった場合、ゲストから切断され、SMBマウント共有へのアクセスからゲストを妨げる。これを避けるために、スーパーユーザのシェルで以下のコマンドを使用することができる。これが適切なオプションであるかどうかは事前に調査しておくこと。

```bash
net config server /autodisconnect:-1
```

## 制限事項

SMBはVagrantにおいて、比較的新しい同期フォルダ種類であるため、粗削りな側面を持っている。願わくば、Vagrantの将来的なバージョンでこれらを対応してほしい。

現時点におけるSMB同期フォルダの第一の制限事項は除去しない、または、掃除しない点である。一度フォルダの共有が定義されると、Vagrantはそれを決して取り除かない。SMB同期フォルダの共有をきれいに掃除するには、定期的にコマンド・プロンプト内で`net share`を実行し、望まない共有があれば`net share NAME /delete`をNAMEにその共有の名前を指定して、それぞれに対して実行する必要がある。

## 共通の問題

### "wrong fs type"エラー

Linux上でマウントしている間に"wrong fs type,"という言葉を含むエラーメッセージをみつけたら、OS内でSMBカーネル拡張がアップデートを必要としていることを示す。

カーネル拡張のアップデートがオプションでなければ、その同期フォルダに対して以下のようなオプションを指定することで問題を回避することが可能である。

```bash
mount_options: ["username=USERNAME","password=PASSWORD"]
```

"USERNAME"と"PASSWORD"は、対象とするSMBのユーザ名とパスワードに置き換えること。

Vagrant 1.8はよりセキュアな証明書ファイル機構を使うようにSMBマウントを変更した。 しかしながら、多くのオペレーティング・システムはSMBに対して、これをサポートしていないBox外の古いファイルシステムの種類を採用している。上記の回避策は動作しないためにもとの非セキュアな状態にVagrantを戻してしまう。

# VirtualBox

VagrantのVirtualBox[プロバイダ](https://www.vagrantup.com/docs/providers/)を使用しているならば、VirtualBox共有フォルダがデフォルトの同期フォルダ種類である。これはゲストからホスト、ホストからゲストへファイルの変更を同期する為にVirtualBox共有フォルダシステムを使用してフォルダを同期する。

## 警告

`sendfile`に関連する、ファイルの原型が損なわれたり、ファイルが更新されたなかったりする[VirtualBoxのバグ](https://github.com/mitchellh/vagrant/issues/351#issuecomment-1339640)が存在する。稼働するいかなるWebサーバにおいても、`sendfile`を非活性にするべきである。

Nginxでは:

```bash
sendfile off;
```

Apacheでは:

```bash
EnableSendfile Off
```

# 関連記事

* 前の記事：[【Vagrantドキュメント意訳】10.ネットワーク](http://qiita.com/ringo0321/items/4ebc0ac3bb98240f65ce)
* 次の記事：[【Vagrantドキュメント意訳】12.マルチ・マシン](http://qiita.com/ringo0321/items/1a6ebccfb2733f6e2de1)