## VagrantとDocker
ここ最近の週末はVagrantとDockerを使ってサーバを建てる練習をしています。
VagrantとDockerについてここでは深く説明しませんが、Vagrantは仮想環境の構築をファイル1つで自動化してくれるもので、Dockerも仮想環境なのですが、コンテナと呼ばれる形で仮想環境を作れます。コンテナ型はホストOSのカーネルを利用するため、ゲストOSのオーバーヘッドが少なくなり、処理が早いです。
実世界を見ると1台のサーバにLAMPを全て入れて動かしているのではなく、WebサーバであればWebサーバ1台、DBサーバであればDBサーバ1台など複数のサーバによってなされています。Dockerはそうした実世界のサーバ間とのやり取りを実現してくれるものです。
つまりVagrantで1つの仮想環境を立ち上げ、Dockerで複数台のサーバの代わりをVagrant上に展開することができます。
どちらも環境の構築と破棄が1つのコマンドで行えるため、頻繁にテスト環境をつくるときや移行を行う際にハードウェアに左右されにくい環境を作れます。
## コンテナで立ち上げたWebサーバのコンテンツを編集したい
私が利用しているパソコンのホストマシン(ホストOS)、Vagrantで立ち上げたLinuxの環境をゲストOSと呼ぶことにします。
ホストマシンのディレクトリとゲストOSのディレクトリを繋ぎ、ゲストOSとDockerコンテナ上のディレクトリを繋ぐことで、ホストマシンのディレクトリとコンテナのディレクトリを共有することができます。
ホストマシンのファイルの変更をコンテナ上のファイルと同期することで、ゲストOSとコンテナを意識することなくファイルの編集ができるのですが、通常では`vagrant up`を行った段階でしかホストマシンとゲストOSでは同期されません。
いくらホストマシン上で変更を行ってもゲストOS上のファイルには反映されないし、ゲストOS上のファイルを編集してもコンテナには反映されますが、ホストマシン上では変更されないので`vagrant halt`をするとゲストOS上の変更は消えてしまいます。
そのためVagrantfileに記述を加え、ホストマシンとゲストOSのリアルタイム同期を実現します。Vagrantfileの詳しい書き方については省略。
```ruby
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.network "forwarded_port", guest: 80, host: 80
config.vm.synced_folder "./", "/vagrant", type: "rsync" # <- 追記
config.vm.provision "docker" do |d|
d.run "httpd", args: "-d -p 80:80 -v /vagrant/public_html:/usr/local/apache2/htdocs"
end
end
```
ホストマシンで`vagrant up`を行う際のフォルダがカレントディレクトリになり、ゲストOSのvagrantというディレクトリと共有されるのはVagrantfileに記述しなくても自動で行われるのですが、`type: "rsync"`でリアルタイム同期が実現できるため改めて記述します。
ここではホストマシンの`./public_html`とコンテナの`/usr/local/apache2/htdcos`が共有されます。
この状態でホストマシン上のファイル(index.htmlなど)を編集し、`vagrant rsync`というコマンドでゲストOSのファイルに変更を反映すると、Web上にも反映することができます。編集のたびコマンドを実行するのは面倒なのですが、`vagrant rsync-auto`と実行することでファイルの保存のたび反映してくれるようになります。
1つ問題として`rsync`はホストマシンとゲストOSの双方向ではないようなので、ゲストOSで編集したものはホストマシンに反映されません(ホストマシンのVSCodeが使いたいので問題ではない)。