Why Vagrant + Virtual Box
學習Rails 的過程,會使用Mac 的Parallels Desktop 建立Ubuntu 當作Production,使用幾次之後覺得有點麻煩,如果要再擴大系統架構,就玩不下去了,於是google 搜尋找到了Vagrant + Virtual Box 的組合,覺得這是不錯的組合,寫篇文章紀錄一下
Installtion
安裝Vagrant, Virtual 這兩套軟體
概念
Box 可以從Vagrant網站下載,Box 是Virtual Box 專用的,表示一個Virtual Machine (VM),而官方提供的Box 又稱為Base,也就是最基本的VM
新增 Box
可以到官網 查詢要用什麼box_name (vm)
這次介紹使用 ubuntu/trusty64
1
2
3
$ vagrant box add [box_name]
# e.g.
$ vagrant box add ubuntu/trusty64
初始化
這邊有點抽象不太好理解,可能多操作幾次,就可以理解接下來說明的內容
每初始一個VM 都會建立一個對應的Vagrantfile,而這VM 已與原本的Base 衍生出來(或解讀為Base 的Instance)
1
2
3
4
$ mkdir vagrant-test && cd vagrant-test
$ vagrant init [box_name]
# e.g.
$ vagrant init ubuntu/trusty64
Configuration of Vagrantfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# 預設是true
# 不檢查更新版本
# config.vm.box_check_update = false
# 設定使用的 Box
config.vm.box = "ubuntu/trusty64"
# 設定虛擬主機的所使用的記憶體,可以避免在虛擬主機 bundle install 時,記憶體不足的錯誤
config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "1024"]
end
# 設定虛擬主機僅供自己使用的 ip (注意設跟自己的虛擬ip 同一個網域)
config.vm.network :private_network, ip: "10.10.10.10"
# 設定主機名稱
config.vm.hostname = "ubuntu-rails"
# Forward the Rails server default port to the host
config.vm.network "forwarded_port", guest: 80, host: 8080
# Forward the Redis default port to the host
# config.vm.network "forwarded_port", guest: 6379, host: 6379
end
操作指令
開機
使用ssh 連線到VM
重開 (修改 vagrantfile 後需要重開)
暫停 <-> 恢復
1
2
$ vagrant suspend
$ vagrant resume
關機
Others
VM 狀態
列出box 清單
查看所有指令清單
1
$ vagrant list-commands
Vagrant 允許使用Provisioner 自動安裝或調整設定內容,就是在啟動VM 之後,執行已設定的腳本或軟體
Vagrant 提供三種自動化 provisioning 機制:
inline script(內嵌腳本)
external script file(外部腳本檔)
configuration management software(組態管理軟體)
在Vagrantfile 中設定要使用哪種provision
1
2
3
4
5
6
7
8
9
10
# inline script
config.vm.provision "shell", inline: "nginx -v"
# external script file
config.vm.provision "shell", path: "check_env.sh"
# configuration management software
config.vm.provision "chef_solo" do |chef|
# ...
end
打包自己專用的BOX
如果每個VM 都要因應不同需求安裝對應的軟體,實在非常費時費工
可以透過package
把已經設定好的VM 打包變成Box,如果日後有需求,可以根據此Box 初始一個新的VM
1
2
3
4
5
6
7
8
9
10
# 指令會在你目前的資料夾下建立一個myFirstVM.box
$ vagrant package --output myFirstVM.box
# 將box 加入清單
$ vagrant box add [box_name] myFirstVM.box
# e.g.
$ vagrant box add ubuntu-nginx-rails-redis myFirstVM.box
# 初始化
$ vagrant init ubuntu-nginx-rails-redis
多機環境
只有一個VM 是還不夠的,Vagrant 是很強大的,可以在Vagrantfile 設定多主機的環境
以下示範建立 app * 1 + db * 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# as rails-app
config.vm.define :app do |app_config|
app_config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "512"]
end
app_config.vm.box = "ubuntu/trusty64"
app_config.vm.host_name = "app"
app_config.vm.network :private_network, ip: "10.10.10.10"
end
# as mysql database
config.vm.define :db do |db_config|
db_config.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "512"]
end
db_config.vm.box = "ubuntu/trusty64"
db_config.vm.host_name = "db"
db_config.vm.network :private_network, ip: "10.10.10.11"
end
end
後記
指令不熟悉可以透過 vagrant -h
找到答案
vagrant 是非常強大的工具,也可以串接AWS 或 Docker,有空再來寫篇文章吧
Reference