使用 Vagrant 構建開發環境


使用 Vagrant 構建開發環境

摘要:本文描述了如使用 Vagrant 構建統一的開發環境。

問題

作為開發人員,我們通常面臨的問題有:

  1. 開發環境需要手工安裝配置,這包括操作系統(CentOS、Ubuntu)、PHP/HHVM、Python、Node.js、MySQL、Apache/Nginx等的版本和配置。
  2. 無法重現問題。
    甲:你說的問題,怎么在我的機器上沒事兒啊?
    乙:可問題的確存在,不信你到我的機器上來看。
    甲:那我的機器和你的環境哪里不同呢?
    因為環境不同,比如開發環境和生產環境不同,和測試環境也不完全相同。
  3. 團隊中沒有統一的方法配置開發環境,保持相同的環境,好的可能會有一個文檔,告訴大家要下載、安裝的東西,缺乏文檔的可能就要到處問了。
  4. 在同一台機器上,要為參與的不同項目配置不同的環境,因為要求的軟件、版本不同,有時候這根本就不可能。
  5. 團隊中不同的成員使用的機器、操作系統就不同,就很難保證完全相同的環境。比如很多開源項目,團隊成員來自五湖四海,有人用Windows,有人用Mac,系統不一樣,配置就可能不同,導致不同的結果。

解決方法 - Vagrant之道

用虛擬機構建一致的環境,並且把安裝和配置的過程自動化,這就是Vagrant所做的事情。按照Vagrant的流程:

  • 系統工程師只需要准備Vagrant配置以及相應的腳本,來配置虛擬機。
  • 團隊成員只需要從源碼控制中簽出代碼,運行vagrant up,就可以有一個完整的開發環境了。開發人員還是可以繼續在自己的機器上使用自己熟悉的編輯器、瀏覽器和其它工具,而代碼及數據庫、web服務器則是運行在Vagrant的虛擬機中。
  • 如果把虛擬機搞亂了,只需要用vagrant destroy把虛擬機刪除,再運行vagrant up就又可以得到事先配置好的虛擬機了。
  • 用完之后,只需要使用vagrant halt或者vagrant suspend把虛擬機關機或者休眠,第二天用vagrant up就把虛擬機重新啟動,恢復到昨天的狀態了。
  • 這種對虛擬機的管理方式,不單在一個項目的團隊中可以使用,而且可以跨多個項目使用。使用相同的流程和環境,提高了生產力,再也不會有“在我的機器上明明沒有這個問題”的問題了。

這就是Vagrant之道(參看[5]第4頁)。

Vagrant可以做下面這些事情:

  • 通過SSH登錄虛擬機
  • 關掉虛擬機
  • 刪除虛擬機,完全刪除虛擬硬盤和配置信息
  • 暫停和恢復虛擬機
  • 把虛擬機打包,從而可以分發給其他開發人員

Vagrant涉及的概念:

  • Vagrant本身並不是虛擬機,它通過其供應商(provider)來使用虛擬機,支持的虛擬機有Oracle的VirtualBoxVMWareVMWare FusionVMWare Workstation和微軟的Hyper-V,以及象Docker這樣的容器,還有Amazone的AWSRackspaceDigitalOcean等公有雲。缺省的是使用VirtualBox,因為這是免費的,也是最容易配置的。
  • 虛擬機只是提供了一個虛擬的機器,其中的各種軟件的安裝和配置還是要靠provision,支持的配置工具有最基本的shell腳本、以及PuppetChefAnsible等等。
  • 為了便於虛擬機的分發和共享,虛擬機本身的虛擬硬盤和配置加上Vagrant的設置文件可以打包在一起,這在Vagrant中叫box,這是可被Vagrant直接使用的虛擬機鏡像文件。眾多廠商和用戶在Atlas(以 前叫Vagrant Cloud)上提供了各種box,對應你所使用的provider。你也可以在其它box的基礎上,進一步配置、發布自己的box,共享給自己的團隊或者公眾。
  • 如果上述的功能還不能滿足你對環境的要求,Vagrant還提供插件,對基本的功能進行擴展,甚至你也可以按照其規范開發自己的插件,滿足特定的要求。

下面我們就用幾個例子來說明Vagrant的使用。

請先下載、安裝VirtualBoxVagrant。因為Vagrant是用ruby開發的,你還要下載、安裝Ruby。不論你的機器是Windows、Mac或者各種Linux發行版本,這幾個軟件都有相應的版本。

實例一 最簡單的Vagrant環境

創建一個新目錄,比如叫example。然后運行:

vagrant init hashicorp/precise64

在上述命令中指定了hashicorp/precise64為使用的box,這是Ubuntu 12.04 LTS,更多的信息可見https://atlas.hashicorp.com/hashicorp/boxes/precise64。第一次需要一個box時(即在運行vagrant up時),Vagrant會自動下載該box到你的機器上,這通常位於<homedir>\.vagrant.d\boxes(例如,在Windows 7上,這就是C:\Users\myusername\.vagrant.d\boxes),以后就不必再次下載了。

上述會生成一個基本的Vagrant配置文件Vagrantfile,最簡單的情況可以只有這一個文件。基本內容如下:

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "hashicorp/precise64"

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  config.vm.network "forwarded_port", guest: 80, host: 8080
end

 這個文件指定了下面這些基本的配置:

  • 在上述生成的配置文件中,指定了如下box:
    config.vm.box = "hashicorp/precise64"
  • 其次,指定虛擬機和主機之間的映射目錄,通常共享的是源文件目錄。這樣,你就可以在主機上繼續使用自己熟悉的編輯器寫代碼,而使用虛擬機環境來運行、調試。
    上述配置文件沒有指定任何映射目錄,但是Vagrant缺省會把主機Vagrantfile配置文件所在的目錄映射為虛擬機上的/vagrant目錄。
  • 還有,就是配置虛擬機的網絡,否則,你從主機上無法訪問虛擬機。這有三種模式:forwarded ports、host-only networking和bridged networking。
    • Forwarded Ports,缺省值,在主機上選擇一個端口,轉發給虛擬機的一個端口,這樣就不必給虛擬機一個IP,就可以從主機訪問虛擬機了。
      上述配置文件中,使用的是Forwarded Ports:
      config.vm.network "forwarded_port", guest: 80, host: 8080

      這會把虛擬機的80端口映射到主機的8080端口,在主機上通過localhost:8080就可以訪問虛擬機了。同時,缺省會有另外一個映射,把虛擬機的22端口映射到主機的2222端口,這是為了允許從主機上通過SSH登錄到虛擬機。

    • Host-Only Networking,這會在主機上創建一個僅對主機和虛擬機可見的私有網絡,這樣虛擬機得到一個指定的靜態IP地址,就可以從主機通過該靜態IP地址來訪問虛擬機了,而虛擬機也可以通過*.*.*.1的IP地址來訪問主機。這種情況下,主機所在的網絡上的其他機器是無法“看到”這個私有網絡的,也就無法訪問虛擬機。
    • Bridged Networking,橋接虛擬機到主機上的一個設備(應該指網卡),這樣虛擬機就如同主機所在網絡上的另外一台物理機器一樣,這意味着虛擬機可以訪問網絡資源,網絡上的其他機器也可以訪問虛擬機。

有了這個Vagrantfile配置文件,就可以啟動虛擬機了。在命令行中,在Vagrantfile所在的目錄中,運行如下命令:

vagrant up

小竅門:在Windows 7(及以上版本?)的Windows Explorer中,可以按住Shift鍵,再用鼠標右擊某個目錄,直接在跳出的上下文菜單中點擊"Open command window here",就直接進入命令行並進入該目錄了。

輸出如下:

 從上面的輸出中,我們可以看到指定使用的box、端口的映射和共享目錄的映射。

前面提到虛擬機22端口對主機2222端口的映射是用於SSH的,我們現在就可以用SSH登錄虛擬機了。運行如下命令:

vagrant ssh

小竅門:如果你的命令行沒有對ssh的支持,就無法登錄。在Windows上,可以在安裝git的時候,有一個選項,選擇添加相應的目錄到系統路徑中,就支持在命令行使用SSH了。

上述命令相應的輸出為:

這就登錄進入了虛擬機,在$提示符下可以使用Linux命令操縱虛擬機了。

實例二 Python Sphinx文檔環境

第二個例子中,我們用VirtualBox和shell腳本來構建一個最基本的虛擬環境,用於使用Sphinx來生成文檔。先創建一個新目錄,比如叫docs,在其中創建一個新文件Vagrantfile,完整的配置為:

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "puphpet/ubuntu1404-x64"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"
  config.vm.synced_folder ".", "/docs"

  config.vm.provider "virtualbox" do |v|
    v.name = "cakephp_docs"
    v.memory = 384
  end

  config.vm.provision :shell, path: "provision.sh"
end

 最常用的Linux版本之一是Ubuntu 14.04,我們就以此為基礎,在配置中指定使用puppet/ubuntu1404-x64 box:

  config.vm.box = "puphpet/ubuntu1404-x64"

映射主機的當前目錄(即Vagrantfile配置文件所在的目錄)為虛擬機的/docs目錄,這里會放置源代碼控制下的文檔源碼*.rst文件:

  config.vm.synced_folder "./", "/docs"

另外,因為不需要從主機訪問虛擬機的web服務器,所以沒有配置網絡,即使用的是缺省的Forwarded Ports模式。

再指定使用一個shell腳本,安裝、配置sphinx:

  config.vm.provision :shell, path: "provision.sh"

在同一目錄下,再創建shell腳本文件povision.sh,其內容為:

#!/usr/bin/env bash

echo "update apt repository..."
apt-get update >/dev/null 2>&1
echo "Installing python-setuptools..."
sudo apt-get install -y python-setuptools >/dev/null 2>&1
echo "Installing easy_install..."
sudo apt-get install -y easy_install >/dev/null 2>&1
echo "Installing sphinx..."
sudo easy_install sphinx==1.2 >/dev/null 2>&1
echo "Installing sphinxcontrib-phpdomain..."
sudo easy_install sphinxcontrib-phpdomain >/dev/null 2>&1

因為Python是Linux自帶的,不需要再安裝了。該腳本使用apt-get安裝兩個軟件包python-setuptools和easy_install,然后再用easy_install安裝sphinx 1.2和sphinxcontrib-phpdomain。

這樣就配置好了,在命令行中,在Vagrantfile所在的目錄中運行

vagrant up
vagrant ssh

之后,就通過SSH登錄到虛擬機,可以在其中用sphinx從源代碼構建html文檔了。

實例三 LAMP開發環境

在第三個例子中,我們使用PuPHPet為PHP配置一個LAMP開發環境。PuPHPet是一個網頁的向導式界面,讓你更容易地生成使用Puppet的Vagrant配置文件。

用瀏覽器打開https://puphpet.com

第一步,選擇部署目標,缺省為本地,使用VirtualBox。我們選擇操作系統為Ubuntu 14.04 64位,如下圖所示:

Provider和VM操作系統

然后,設置虛擬機IP地址、內存、端口,以及目錄映射,注意這里的目錄是用來作為網站應用根目錄的,如下圖所示:

IP地址、內存、端口,以及目錄映射

第二步,選擇要在虛擬機上安裝的軟件包。我們選擇Ubuntu的htop和vim,如下圖所示:

Server Packages

第三步,防火牆規則,不需要做任何設置,略過:

Firewall Rules

第四步,選擇web服務器,我們選擇使用Apache,要安裝rewrite模塊,如下圖所示:

Webservers

再設置域名、網站根目錄,允許設置多個VHOST,如下圖所示:

Webservers - Apache Virtual Host

注意上面的Document Root路徑和在第一步中設置的目錄映射有關。

第五步,選擇語言PHP,以及相關的設置和需要的模塊,如下圖所示:

Languages

還可以選擇需要的PHP庫,如下圖所示:

PHP Modules/Libraries

第六步,選擇數據庫MySQL,並且設置管理員密碼,如下圖所示:

Databases

然后創建數據庫,允許創建多個數據庫,如下圖所示:

MySQL Create User  & Database

其中,/var/www/database/backup/2014-10-19_cakephp_blog.sql是在虛擬機中要恢復的數據庫備份,這個路徑也和你在第一步中設置的目錄映射有關。

第七步,選擇其它工具,包括郵件工具Mailcatcher、隊列工具Beanstalkd及RabbitMQ、搜索工具Elastic Search及Solr,如下圖所示:

Additional Tools

我們不使用任何額外工具,所以略過這一步。

第八步,也就是最后一步,完成,如下圖所示:

Create Your Manifest

點擊那個大大的藍色按鈕“GO AHEAD THEN, MAKE IT!”,就可以下載一個將近3MB的puphpet.zip。打開這個.zip文件,可以看到按照我們前面第一至八步設置的Vagrantfile配置以及相應的Puppet模塊,如下圖所示:

puphpet.zip

把它解壓到一個目錄中,這些文件可以和PHP項目的源代碼一起放入源碼控制中,供項目團隊的其他成員使用。

在命令行中,在Vagrantfile所在的目錄中運行vagrant up,就可以得到一個運行的LAMP虛擬機了。

在主機的hosts文件中,按照第四步的設置加入下面這行:

192.168.56.102    www.cakephp3.dev                # CakePHP 3

就可以在主機的瀏覽器上通過www.cakephp3.dev訪問虛擬機上的網站了。

Vagrant的常用命令

vagrant up  # 啟動、配置虛擬機
vagrant suspend  # 休眠虛擬機
vagrant halt  # 關閉虛擬機
vagrant destroy  # 刪除虛擬機
vagrant status  # 當前目錄下Vagrantfile配置對應的Vagrant虛擬機的狀態,以及在此狀態下可以使用的命令
vagrant global-status  # 本機上所有Vagrant虛擬機的狀態

更多的命令可以參考[3]中的Command-Line Interface

進一步的思考

  • 打包、分發box,這是Vagrant通過box以及Atlas提供的功能。
  • 使用Docker的provider,可以節省資源,極大地縮短虛擬機的啟動時間,也利於生產環境的部署。
  • 是否可以使用Vagrant來配置Windows虛擬機?應該使用什么provision?是否可以使用PowerShell?
  • 是否可以使用Vagrant來配置Mac虛擬機?可能不行,至少在Atlas上沒有找到Mac的box。而且,恐怕也沒必要。

參考資料

  1. Vagrant官網
    https://www.vagrantup.com/
  2. Vagrant Getting Started
    https://docs.vagrantup.com/v2/getting-started/
  3. Vagrant Documentation
    https://docs.vagrantup.com/v2/
  4. Atlas (之前叫Vagrant Cloud)
    https://atlas.hashicorp.com
  5. Vagrant: up and running, ISBN 978-1-449-33583-0
    http://shop.oreilly.com/product/0636920026358.do
  6. Hello Vagrant - 黃博文
    http://www.cnblogs.com/huang0925/p/3349841.html
  7. Docker與Vagrant之間的特點比較
    http://www.cnblogs.com/vikings-blog/p/3973265.html
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM