1+1>2:用Docker和Vagrant構(gòu)建簡潔高效開發(fā)環(huán)境
譯文Docker和Vagrant經(jīng)常被認(rèn)為是兩種相互替代的工具,其實它們可以結(jié)合使用,構(gòu)建隔離的、可重復(fù)的開發(fā)環(huán)境。我們將證明該環(huán)境可以構(gòu)建一個Docker容器以便開發(fā)Java應(yīng)用程序,并充分利用Vagrant的強(qiáng)大功能,以解決一些現(xiàn)實當(dāng)中的實際問題。
這篇博客的第一部分探討了開發(fā)環(huán)境的常見缺陷、簡單Docker環(huán)境的構(gòu)建以及Vagrant+Docker配置具有的優(yōu)點。但是如果你想就開始使用Docker和Vagrant,不妨直接跳到本文的這個章節(jié):使用Vagrant,讓Docker容器易于移植。
開發(fā)環(huán)境有什么問題?
要花很長的時間來構(gòu)建
新的開發(fā)人員要花多長時間才能構(gòu)建好當(dāng)前項目的開發(fā)環(huán)境?答案取決于諸多因素(項目時間、從事該項目的開發(fā)人員數(shù)量等),但至少需要半天時間并不罕見。
嘿!其實應(yīng)該比這快得多:查看腳本,執(zhí)行腳本。就是這樣。這兩個步驟應(yīng)該足以構(gòu)建你的環(huán)境,并準(zhǔn)備隨時開發(fā)。
它可能與測試環(huán)境和生產(chǎn)環(huán)境大不一樣
你有沒有因構(gòu)建的環(huán)境在機(jī)器上未通過而跳過自動化測試?或者更糟糕的是,即使更改的內(nèi)容在機(jī)器上順利編譯,但是在持續(xù)整合(CI)服務(wù)器上老是失敗,你有沒有查過問題的根源出在哪里?
任何稍有不同,就會導(dǎo)致意料不到的行為。有的方法可能很簡單,比如試一試框架的上一個版本,或者改用不同的項目。
查明什么導(dǎo)致你的系統(tǒng)出現(xiàn)不同行為是每個開發(fā)人員都應(yīng)該避免的煩人任務(wù)。
虛擬機(jī)和Docker
因而,開發(fā)環(huán)境應(yīng)該具有兩個特點:
隔離:你不希望在測試某個新工具或不同項目時弄得一團(tuán)糟。
可重復(fù):同一個環(huán)境應(yīng)該在每個團(tuán)隊成員的機(jī)器、持續(xù)整合服務(wù)器和生產(chǎn)服務(wù)器上都一再可復(fù)制。
虛擬機(jī)環(huán)境確保了這些特性,可是典型的虛擬機(jī)很耗費資源。開發(fā)人員需要每隔幾分鐘編碼/構(gòu)建/測試,不會接受虛擬化帶來的開銷。
這時候,Docker顯得大有幫助。相比典型的虛擬機(jī),其輕型容器極其快速,而且在開發(fā)人員當(dāng)中極受歡迎。下面是來自Docker博客的一段摘要,解釋了這種成功的原因:
在問世后的頭12個月內(nèi),Docker在初創(chuàng)企業(yè)和早期采用者當(dāng)中迅速流行起來,他們重視該平臺的這一功能,即可以將應(yīng)用程序開發(fā)管理的問題與基礎(chǔ)設(shè)施提 供、配置和運營的問題分離開來。Docker為這些早期用戶提供了一種新穎的、更迅速的方法,可以構(gòu)建分布式應(yīng)用程序,另外提供了一種“編寫一次到處運 行”的部署選擇,部署對象從筆記本電腦、裸機(jī)、虛擬機(jī)到私有云/公有云,不一而足。 |
使用Docker來配置的、可重復(fù)的開發(fā)環(huán)境
為了舉例說明,我們將構(gòu)建一個構(gòu)建并測試Vert.x HTTP服務(wù)器的Docker容器。
Vert.x是一種輕型應(yīng)用程序框架,鼓勵小型、獨立微服務(wù)的架構(gòu)。微服務(wù)“就是一種小巧的獨立式可執(zhí)行程序,可與其他的獨立式可執(zhí)行程序進(jìn)行溝通”(Uncle Bob,http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html)。我們認(rèn)為,它在Docker容器中再合適不過了,這就是為什么我們在此選擇它作為例子。
要是你之前還沒有安裝過Docker,先安裝它。你可以參閱官方文檔(https://docs.docker.com/installation/),或者使用get docker script(https://get.docker.io)來安裝它。我們假設(shè)在本章節(jié)中,我們在Linux上運行。即使Docker也可以安裝到Windows和Mac上(借助boot2docker),我們會在下一章中看到如何使用Vagrant來安裝、為什么Vagrant是一種更好的選擇。
#p#
Docker文件(Dockerfile)
為了描述容器,我們需要一個Docker文件:
FROM ubuntu:14.04
# 安裝開發(fā)工具:jdk和git等
- RUN apt-get update
- RUN apt-get install -y openjdk-7-jdk git wget
# jdk7是默認(rèn)JDK
- RUN ln -fs /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java /etc/alternatives/java
# 安裝vertx
- RUN \
- mkdir -p /usr/local/vertx && cd /usr/local/vertx && \
- wget http://dl.bintray.com/vertx/downloads/vert.x-2.1.2.tar.gz -qO - | tar -xz
# 將vertx添加到路徑
- ENV PATH /usr/local/vertx/vert.x-2.1.2/bin:$PATH
- RUN mkdir -p /usr/local/src
- WORKDIR /usr/local/src
- CMD ["bash"]
Docker文件確實簡單直觀,當(dāng)你需要更深入地挖掘時,有一份出色的在線參考手冊(https://docs.docker.com/reference/builder/)。
FROM ubuntu:14.04定義了我們依賴的基本映像。你可以在docker中心(registry.hub.docker.co)找到Docker基本映像的完整列表。就這個例子而言,我們使用了docker團(tuán)隊構(gòu)建Docker所用的基本映像。
后面幾行描述了將應(yīng)用到基本映像上的改動:
- 使用apt-get安裝開發(fā)工具:openjdk、git、wget
- 下載和安裝vertx
- 將vertx二進(jìn)制文件夾添加到路徑
- 創(chuàng)建文件夾/usr/local/src,并讓它成為默認(rèn)的工作目錄
一旦我們拷貝了Docker文件,就可以構(gòu)建Docker映像:
- $ sudo docker build -t=vertxdev .
獲得源代碼
我們剛構(gòu)建的映像已安裝了git。我們可以用它從Github獲取源代碼:
- $ sudo docker run -t --rm -v /src/vertx/:/usr/local/src vertxdev git clone https://github.com/vert-x/vertx-examples.git
請注意:git在容器里面運行,源代碼因而在容器里面?zhèn)魉?確切的位置是在文件夾/usr/local/src)。為了讓代碼具有持續(xù)性,即使在容器停止和刪除之后,我們也可以使用標(biāo)志-v /src/vertx/:/usr/local/src,將容器的文件夾/usr/local/src綁定掛載到主機(jī)文件夾/src/vertx。一旦git clone命令完成了執(zhí)行,--rm”就銷毀容器。
構(gòu)建并運行應(yīng)用程序
由于源代碼已獲取,我們將啟動新的容器,這個容器負(fù)責(zé)構(gòu)建并運行vertx示例:HelloWorldServer。要注意:vertx run同時負(fù)責(zé)vertx應(yīng)用程序的構(gòu)建和執(zhí)行。
- $ sudo docker run -d -v /src/vertx/:/usr/local/src -p 8080:8080 vertxdev vertx run vertx-examples/src/raw/java/httphelloworld/HelloWorldServer.java
與前一個容器相反,這個容器在停止后不會被銷毀,暴露端口8080(-p 8080:8080),在后臺運行(-d)。若想看一看vertx run的輸出結(jié)果:
- $ sudo docker logs
- Succeeded in deploying verticle
不妨使用curl,從主機(jī)端測試應(yīng)用程序:
- $ curl localhost:8080
- Hello World
這個簡單例子應(yīng)該足以體現(xiàn)出運行Docker容器有多快速。在Docker容器里面運行g(shù)it clone和vertx run的開銷可忽略不計。
但構(gòu)建的這個環(huán)境很基本。在現(xiàn)實環(huán)境中,純Docker配置存在一些不足,而Vagrant就有助于克服這些不足。
#p#
Docker + Vagrant
Docker(其實是作為Docker模塊的libcontainer)仍需要Linux內(nèi)核3.8或更高版本和x86_64架構(gòu)。這在大大限定了Docker能夠原生運行在其中的環(huán)境。
Vagrant是一種開源軟件,它為跨眾多操作系統(tǒng)構(gòu)建可重復(fù)的開發(fā)環(huán)境提供了一種方法。Vagrant使用提供者(provider)來啟動隔離的虛擬環(huán)境。默認(rèn)的提供者是Virtualbox;自v1.6以來,基于docker的開發(fā)環(huán)境也得到支持。相比幫助Docker在非Linux平臺上運行的其他工具(比如boot2docker),Vagrant具有一些重大優(yōu)點:
配置一次,即可到處運行:Vagrant就是原生支持Docker的系統(tǒng)上的Docker封裝器,同時它可啟動“主機(jī)虛擬機(jī)”,以便在不支持它的系統(tǒng)上運行容器。用戶沒必要操心Docker是不是得到原生支持:同一個配置可適用于每一個操作系統(tǒng)。
- Docker主機(jī)并不局限于boot2docker(Tiny Core Linux的Virtualbox映像),但Debian、Ubuntu、CoreOS及其他Linux發(fā)行版也得到支持。而且可以在比Virtualbox更穩(wěn)定的虛擬機(jī)管理器(比如VMware)上運行。
- Vagrant可以編排Docker容器:同時運行多個容器,并且把它們聯(lián)系起來。
在Linux及其他操作系統(tǒng)上使用Vagrant運行Docker
在下面三個章節(jié)中,我們將探討這每一個要點。
使用vagrant,讓Docker容器易于移植
Vagrant可支持Docker,既作為提供者,又作為配置者。但是為了讓它可以在Windows和Mac上自動創(chuàng)建Docker主機(jī)虛擬機(jī),應(yīng)該將它用作提供者。
我們將重復(fù)使用我們在上面見到的同一個Docker文件。與上面一樣,我們將運行兩個Docker容器,以便執(zhí)行g(shù)it clone和vertx run。不過將改而使用Vagrant命令,而不是Docker命令。
安裝Vagrant(https://www.vagrantup.com/downloads)和Virtualbox(https://www.virtualbox.org/wiki/Downloads),以便能夠運行示例。
Vagrantfile
Vagrantfile描述了Vagrant設(shè)備。我們將使用下列內(nèi)容:
- ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
- Vagrant.configure("2") do |config|
- config.vm.define "vertxdev" do |a|
- a.vm.provider "docker" do |d|
- d.build_dir = "."
- d.build_args = ["-t=vertxdev"]
- d.ports = ["8080:8080"]
- d.name = "vertxdev"
- d.remains_running = true
- d.cmd = ["vertx", "run", "vertx-examples/src/raw/java/httphelloworld/HelloWorldServer.java"]
- d.volumes = ["/src/vertx/:/usr/local/src"]
- end
- end
- end
ENV'VAGRANT_DEFAULT_PROVIDER' = 'docker' 讓我們不必在每個Vagrant命令中指定提供者是Docker(默認(rèn)提供者是Virtualbox)。該文件的其余部分擁有Vagrant構(gòu)建Docker映像和運行容器所用的選項。想了解更多信息,請參閱Vagrantfilehttps://docs.vagrantup.com/v2/vagra...(https://docs.vagrantup.com/v2/vagrantfile/index.html)和Docker提供者(https://docs.vagrantup.com/v2/docker/configuration.html)說明文檔。
獲得源代碼
一旦我們將Vagrantfile拷貝到Dockerfile文件夾中,我們可以運行g(shù)it clone,以獲取源代碼:
- $ vagrant docker-run vertxdev -- git clone https://github.com/vert-x/vertx-examples.git
與之前一樣,git clone完成執(zhí)行后,容器將被銷毀。請注意:我們還沒有構(gòu)建映像,Vagrant自動構(gòu)建了映像。減少了手動步驟。
構(gòu)建并運行應(yīng)用程序
我們能夠構(gòu)建并運行HTTP Hello World服務(wù)器:
- $ vagrant up
在底層,Vagrant將執(zhí)行docker run,啟動容器的命令由d.cmd選項指定。
想獲得vertx run命令的輸出結(jié)果:
- $ vagrant docker-logs
- ==> vertxdev: Succeeded in deploying verticle
測試
在Linux平臺上,只要運行:
- $ curl localhost:8080
- Hello World
在Windows和Mac上,端口8080并不從Docker主機(jī)虛擬機(jī)被轉(zhuǎn)發(fā)到主vagrant主機(jī)(不過Docker容器端口被轉(zhuǎn)發(fā)到Docker主機(jī))。因而,我們需要通過ssh進(jìn)入到Docker主機(jī)虛擬機(jī),以便連接至HTTP服務(wù)器。不妨檢索Vagrant默認(rèn)Docker主機(jī)的ID:
- $ vagrant global-status
- id name provider state directory
- -------------------------------------------------------------------------------------------------------
- c62a174 default virtualbox running /Users/mariolet/.vagrant.d/data/docker-host
一旦檢索到該設(shè)備,我們可以測試HTTP服務(wù)器了:
- $ vagrant ssh c62a174 -c "curl localhost:8080"
- Hello World
#p#
你有說過一模一樣嗎?如何定制Docker主機(jī)?
在不支持容器的平臺上,默認(rèn)情況下,Vagrant啟動一個Tiny Core Linux(boot2docker)Docker主機(jī)。如果我們的持續(xù)整合環(huán)境、試運行環(huán)境或生產(chǎn)環(huán)境不運行boot2docker,我們會在這些環(huán)境的配置之間有一個缺口。這實際上是生產(chǎn)環(huán)境缺陷的根源,不可能在開發(fā)環(huán)境中發(fā)現(xiàn)。不妨試著解決這個問題。
不同環(huán)境上的不同Docker主機(jī):實際上違反安全
如上所見,Vagrant的主要便利之一是,它讓我們可以指定自定義的Docker主機(jī)。換句話說,我們并不被boot2docker和Tiny Core Linux所束縛。
Docker主機(jī)虛擬機(jī)Vagrantfile
我們將使用一個新的Vagrantfile來定義Docker主機(jī)虛擬機(jī)。下面這個文件基于Ubuntu Server 14.04 LTS:
- Vagrant.configure("2") do |config|
- config.vm.provision "docker"
- # 下面這一行終結(jié)所有ssh連接,因此
- # Vagrant將被迫重新連接。
- # 那是在PATH中擁有docker命令的替代辦法
- config.vm.provision "shell", inline:
- "ps aux | grep 'sshd:' | awk '{print $2}' | xargs kill"
- config.vm.define "dockerhost"
- config.vm.box = "ubuntu/trusty64"
- config.vm.network "forwarded_port",
- guest: 8080, host: 8080
- config.vm.provider :virtualbox do |vb|
- vb.name = "dockerhost"
- end
- end
將它保存到原始的Vagrantfile文件夾,名稱為DockerHostVagrantfile。
在自定義的Docker主機(jī)中運行Docker容器
下一步指定使用這個新的虛擬機(jī)作為Docker主機(jī),而不是默認(rèn)主機(jī),因而將下面新的兩行添加到a.vm.provider代碼段:
- config.vm.define "vertxdev" do |a|
- a.vm.provider "docker" do |d|
- [...]
- d.vagrant_machine = "dockerhost"
- d.vagrant_vagrantfile = "./DockerHostVagrantfile"
- end
- end
請注意:配置自定義的Docker主機(jī)有另一個好處:我們現(xiàn)在可以指定自定義的轉(zhuǎn)發(fā)端口:
- config.vm.network "forwarded_port",
- guest: 8080, host: 8080
因而,我們能夠從主主機(jī)操作系統(tǒng)里面訪問vertx HTTP服務(wù)器:
不同環(huán)境上同樣的Docker主機(jī)和端口轉(zhuǎn)發(fā)
當(dāng)然,主機(jī)虛擬機(jī)并不局限于Ubuntu??梢栽赩agrant云(https://vagrantcloud.com)上發(fā)現(xiàn)更多的vagrant設(shè)備。值得關(guān)注的支持Docker的設(shè)備有boot2docker(原始版和改良版)和CoresOS。
#p#
使用Vagrant編排Docker容器
就在不久前,我們還每次只能運行一個Docker容器。然而在現(xiàn)實生活中,我們卻常常需要同時運行多個容器:數(shù)據(jù)庫、http、Web容器等都在單獨的容器中運行。
我們在本章節(jié)將探討使用Vagrant“多機(jī)器”環(huán)境(https://docs.vagrantup.com/v2/multi-machine/),同時執(zhí)行多個docker容器。然而,我們不會考慮Docker容器分布在不同的Docker主機(jī)這一場景:所有容器都在同一個主機(jī)里面運行。
運行多個容器
多個容器
作為第一個例子,我們將使用Vert.x Event Bus Point to Point這個例子。我們利用了在文章開頭定義的同一個Docker文件,并且在新的Vagrantfile文件里面配置了兩個Docker容器:“vertxreceiver”和“vertxsender”:
- ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
- DOCKER_HOST_NAME = "dockerhost"
- DOCKER_HOST_VAGRANTFILE = "./DockerHostVagrantfile"
- Vagrant.configure("2") do |config|
- config.vm.define "vertxreceiver" do |a|
- a.vm.provider "docker" do |d|
- d.build_dir = "."
- d.build_args = ["-t=vertxreceiver"]
- d.name = "vertxreceiver"
- d.remains_running = true
- d.cmd = ["vertx", "run", "vertx-examples/src/raw/java/eventbus_pointtopoint/Receiver.java","-cluster"]
- d.volumes = ["/src/vertx/:/usr/local/src"]
- d.vagrant_machine = "#{DOCKER_HOST_NAME}"
- d.vagrant_vagrantfile = "#{DOCKER_HOST_VAGRANTFILE}"
- end
- end
- config.vm.define "vertxsender" do |a|
- a.vm.provider "docker" do |d|
- d.build_dir = "."
- d.build_args = ["-t=vertxsender"]
- d.name = "vertxsender"
- d.remains_running = true
- d.cmd = ["vertx", "run", "vertx-examples/src/raw/java/eventbus_pointtopoint/Sender.java","-cluster"]
- d.volumes = ["/src/vertx/:/usr/local/src"]
- d.vagrant_machine = "#{DOCKER_HOST_NAME}"
- d.vagrant_vagrantfile = "#{DOCKER_HOST_VAGRANTFILE}"
- end
- end
- end
對這兩個docker容器而言,vagrant_mahchine即Docker主機(jī)虛擬機(jī)的ID是dockerhost。Vagrant要足夠智能化,才能重復(fù)使用dockerhost的同一個實例來運行兩個容器。
想啟動vertxsender和vertxreceiver,把Vagrantfile換成這一個文件,并運行vagrant up:
- $ vagrant up
- ...
- $ vagrant docker-logs
- ==> vertxsender: Starting clustering...
- ==> vertxsender: No cluster-host specified so using address 172.17.0.18
- ==> vertxsender: Succeeded in deploying verticle
- ==> vertxreceiver: Starting clustering...
- ==> vertxreceiver: No cluster-host specified so using address 172.17.0.19
- ==> vertxreceiver: Succeeded in deploying verticle
- ==> vertxreceiver: Received message: ping!
- ==> vertxsender: Received reply: pong
- ==> vertxreceiver: Received message: ping!
- ==> vertxreceiver: Received message: ping!
- ==> vertxsender: Received reply: pong
- ==> vertxsender: Received reply: pong
- ...
即使vertxsender和vertxreceiver根本不知道彼此的主機(jī)名和IP地址,vertx eventbus協(xié)議卻有一項發(fā)現(xiàn)功能,以便連接發(fā)送方和接收方。對于沒有類似功能的應(yīng)用程序而言,Docker提供了容器連接選項。
#p#
連接容器
在這個例子中,我們先運行Docker容器(vertxdev),它啟動我們之前看到的那個HelloWorld Web服務(wù)器。然后,第二個容器(vertxdev-client)將使用wget執(zhí)行HTTP請求:
- ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
- Vagrant.configure("2") do |config|
- config.vm.define "vertxdev" do |a|
- a.vm.provider "docker" do |d|
- d.image = "vertxdev:latest"
- d.ports = ["8080:8080"]
- d.name = "vertxdev"
- d.remains_running = true
- d.cmd = ["vertx", "run", "vertx-examples/src/raw/java/httphelloworld/HelloWorldServer.java"]
- d.volumes = ["/src/vertx/:/usr/local/src"]
- d.vagrant_machine = "dockerhost"
- d.vagrant_vagrantfile = "./DockerHostVagrantfile"
- end
- end
- config.vm.define "vertxdev-client" do |a|
- a.vm.provider "docker" do |d|
- d.image = "vertxdev:latest"
- d.name = "vertxdev-client"
- d.link("vertxdev:vertxdev")
- d.remains_running = false
- d.cmd = ["wget","-qO", "-","--save-headers","http://vertxdev:8080"]
- d.vagrant_machine = "dockerhost"
- d.vagrant_vagrantfile = "./DockerHostVagrantfile"
- end
- end
- end
這個新Vagrantfile文件的重要部分是這一行d.link("vertxdev:vertxdev")。由于這一行,vertxdev-client就能夠解析主機(jī)名vertxdev,因而使用命令wget -qO - --save-headers http://vertxdev:8080,處理HTTP請求。
想運行容器,把Vagrantfile換成這個新文件,并運行vagrant up.。--no-parallel選項確保vertxdev容器在vertxdev-client之前啟動。
- $ vagrant up --no-parallel
不妨看一下日志,以證實發(fā)生的情況:
- $ vagrant docker-logs
- ==> vertxdev: Succeeded in deploying verticle
- ==> vertxdev-client: HTTP/1.1 200 OK
- ==> vertxdev-client: Content-Type: text/plain
- ==> vertxdev-client: Content-Length: 11
- ==> vertxdev-client:
- ==> vertxdev-client: Hello World
#p#
伙計,我的IDE在哪里?
雖然集成開發(fā)環(huán)境(IDE)是開發(fā)環(huán)境的一個重要部分,但我們還沒有討論它。那是由于圖形化應(yīng)用程序并不通常在Docker容器里面運行。Eclipse或IntelliJ等IDE在主主機(jī)中通常很適合,源代碼在主機(jī)和容器之間使用Docker卷來共享。這就是本章節(jié)所介紹的內(nèi)容。
Vagrant隨帶synced_folder選項,以便在docker容器和主主機(jī)之間共享文件夾:
- ENV['VAGRANT_DEFAULT_PROVIDER'] = 'docker'
- Vagrant.configure("2") do |config|
- config.vm.synced_folder ".", "/usr/local/src"
- config.vm.define "vertxdev-src" do |a|
- a.vm.provider "docker" do |d|
- d.build_dir = "."
- d.build_args = ["-t=vertxdev"]
- d.ports = ["8080:8080"]
- d.name = "vertxdev-src"
- d.remains_running = true
- d.cmd = ["vertx", "run", "vertx-examples/src/raw/java/httphelloworld/HelloWorldServer.java"]
- d.vagrant_machine = "dockerhost"
- d.vagrant_vagrantfile = "./DockerHostVagrantfile"
- end
- end
- end
在這個例子中,vertxdev-src文件夾/usr/local/src將與主主機(jī)Vagrantfile文件夾(.)同步。請注意:Vagrant負(fù)責(zé)為我們構(gòu)建Docker卷。
一旦我們把Vagrantfile換成這一個文件,就可以運行g(shù)it clone,再次使用vertxdev-src容器:
- $ vagrant docker-run vertxdev-src -- git clone https://github.com/vert-x/vertx-examples.git
一旦克隆完畢,源代碼將同時出現(xiàn)在容器和主主機(jī)。因而,我們可以直接訪問,還可以編輯文件:
- $ cd vertx-examples/src/raw/java/httphelloworld/
- $ sed -i '' 's/Hello World/I m in a docker container and I feel good/' HelloWorldServer.java
想測試該應(yīng)用程序,運行vagrant up:
- $ cd -
- $ vagrant up
- $ curl localhost:8080
- I m in a docker container and I feel good
結(jié)束語
如果你在處理一系列不同的平臺:一些平臺支持Docker,另一些不支持,那么使用Vagrant來控制Docker容器很有用。在這種場景下,使用Vagrant可以讓構(gòu)建環(huán)境的過程在不同平臺上具有一致性。
作為Vagrant的替代方案,F(xiàn)ig(http://www.fig.sh)無疑值得關(guān)注。Docker雇用Fig的主要開發(fā)人員,大力支持它,將其視作一種構(gòu)建基于Docker的開發(fā)環(huán)境的出色工具。
原文標(biāo)題:Setting up a development environment using Docker and Vagrant