使用 Vagrant 打造跨平台开发环境

Vagrant 是一款用来构建虚拟开发环境的工具,非常适合 php/python/ruby/java 这类语言开发 web 应用,“代码在我机子上运行没有问题”这种说辞将成为历史。

我们可以通过 Vagrant 封装一个 Linux 的开发环境,分发给团队成员。成员可以在自己喜欢的桌面系统(Mac/Windows/Linux)上开发程序,代码却能统一在封装好的环境里运行,非常霸气。

安装步骤

1. 安装 VirtualBox

虚拟机还是得依靠 VirtualBox 来搭建,免费小巧。
下载地址:https://www.virtualbox.org/wiki/Downloads

* 虽然 Vagrant 也支持 VMware,不过 VMware 是收费的,对应的 Vagrant 版本也是收费的

2. 安装 Vagrant

下载地址:http://downloads.vagrantup.com/ 根据提示一步步安装。

此外,还得下载官方封装好的基础镜像:
Ubuntu precise 32 VirtualBox http://files.vagrantup.com/precise32.box
Ubuntu precise 64 VirtualBox http://files.vagrantup.com/precise64.box

如果你要其他系统的镜像,可以来这里下载:http://www.vagrantbox.es/

* 鉴于国内网速,我们将下载镜像的步骤单独剥离出来了

3. 添加镜像到 Vagrant

假设我们下载的镜像存放路径是 ~/box/precise64.box,在终端里输入:

  • $ vagrant box add hahaha ~/box/precise64.box

hahaha 是我们给这个 box 命的名字,~/box/precise64.box 是 box 所在路径

4. 初始化开发环境

创建一个开发目录(比如:~/dev),你也可以使用已有的目录,切换到开发目录里,用 hahaha 镜像初始化当前目录的环境:

$ cd ~/dev # 切换目录

$ vagrant init hahaha # 初始化

$ vagrant up # 启动环境

你会看到终端显示了启动过程,启动完成后,我们就可以用 SSH 登录虚拟机了,剩下的步骤就是在虚拟机里配置你要运行的各种环境和参数了。

$ vagrant ssh  # SSH 登录
$ cd /vagrant  # 切换到开发目录,也就是宿主机上的 `~/dev`

~/dev 目录对应虚拟机中的目录是 /vagrant

Windows 用户注意:Windows 终端并不支持 ssh,所以需要安装第三方 SSH 客户端,比如:Putty、Cygwin 等。

5. 其他设置

Vagrant 初始化成功后,会在初始化的目录里生成一个 Vagrantfile 的配置文件,可以修改配置文件进行个性化的定制。

Vagrant 默认是使用端口映射方式将虚拟机的端口映射本地从而实现类似 http://localhost:80 这种访问方式,这种方式比较麻烦,新开和修改端口的时候都得编辑。相比较而言,host-only 模式显得方便多了。打开 Vagrantfile,将下面这行的注释去掉(移除 #)并保存:

config.vm.network :private_network, ip: "192.168.33.10"

重启虚拟机,这样我们就能用 192.168.33.10 访问这台机器了,你可以把 IP 改成其他地址,只要不产生冲突就行。

6. 打包分发

当你配置好开发环境后,退出并关闭虚拟机。在终端里对开发环境进行打包:

$ vagrant package

打包完成后会在当前目录生成一个 package.box 的文件,将这个文件传给其他用户,其他用户只要添加这个 box 并用其初始化自己的开发目录就能得到一个一模一样的开发环境了。

7. 常用命令

$ vagrant init  # 初始化
$ vagrant up  # 启动虚拟机
$ vagrant halt  # 关闭虚拟机
$ vagrant reload  # 重启虚拟机
$ vagrant ssh  # SSH 至虚拟机
$ vagrant status  # 查看虚拟机运行状态
$ vagrant destroy  # 销毁当前虚拟机

更多内容请查阅官方文档 http://docs.vagrantup.com/v2/cli/index.html

8. 注意事项

使用 Apache/Nginx 时会出现诸如图片修改后但页面刷新仍然是旧文件的情况,是由于静态文件缓存造成的。需要对虚拟机里的 Apache/Nginx 配置文件进行修改:

# Apache 配置添加:
EnableSendfile off

# Nginx 配置添加:
sendfile off;

SegmentFault 团队就是用这种方式统一开发环境的
本篇文章所用程序版本 VirtualBox 4.2.16,Vagrant 1.2.7

 

使用 Vagrant 搭建本地开发环境的教程

你在本地搭建了一个开发环境,可能是为 php 准备的,你在这个本地的开发环境上面做了一个项目,当你把它迁移到真正的服务器上的时候,你发现了一些问题。这很可能是因为你的本地开发环境与服务器的生产环境之间是有区别的。慢慢地,你又想试一下 node ,因为它跟 JavaScript 的关系不错。或者又对 ruby 产生了兴趣,只因为她有个好听的名字。尝试这些你都需要去安装一些软件,去配置它们的运行环境,你越来越发现,管理这些环境可能会是个问题。

Vagrant 可以让你为每个项目都创建一个虚拟机,你可以选择虚拟机运行的操作系统,去配置需要的环境,比如安装 Web 服务器,数据库管理系统等等。项目的目录可以放在你的电脑上,它会跟虚拟机上的一个目录同步。你的电脑与虚拟机之间可以相互访问,所以,你可以像往常一样,用自己喜欢的编辑器去开发 Web 应用,然后用虚拟机上配置好的环境去运行你的项目。使用 Vagrant,你可以在本地电脑上用虚拟机去配置一个跟 Web 应用的生产环境一样的环境,一样的操作系统,一样的软件,一样的配置。你还可以与团队里的其他成员分享你的开发环境,

准备

下载并安装下面这两样东西:

VirtualBox 是一款开源免费的虚拟机软件,跨平台,Windows ,OS X 都可以使用。Vagrant 也是跨平台的。这篇文章里的演示是在 OS X 操作系统下面完成。

box

box 就是虚拟机的镜像,可以在 Vagrant Cloud 里面下载到,你可以选择自己想要的操作系统,这里我要用的是 CentOS 6.5,因为我的网站的生产环境,也打算用 CentOS 6.5 这个操作系统。这里我要用的是:

chef/centos-6.5

回到命令行工具,去把这个 box 下载到本地电脑上,并且添加到 vagrant 里面:

vagrant box add chef/centos-6.5

返回:

==> box: Loading metadata for box 'chef/centos-6.5'
    box: URL: https://vagrantcloud.com/chef/centos-6.5
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) virtualbox
2) vmware_desktop

因为我们用的是 VirtualBox ,所以,这里应该选择第一个选项,输入数字 1,然后回车。 这样 vagrant 会从 Vagrant Cloud 上下载我们指定的 box 。因为镜像包含操作系统,所以一般都比较大,几百 MB 到 几个 G 都有。

完成以后,输入下面命令来查看可以使用的 box :

vagrant box list

返回:

chef/centos-6.5 (virtualbox, 1.0.0)

现在,就可以用 CentOS-6.5 这个版本的操作系统来运行我们要开发的 Web 应用了。

初始化

打开命令行工具,OS X 上面可以使用系统自带的终端工具,Windows 用户可以用命令提示符工具。然后先为项目创建一个目录,可以放在任何地方。我打算在当前登录用户的桌面上,创建一个叫 ninghao.net 的目录:

cd ~/desktop
mkdir ninghao.net

进入到为项目创建的这个目录:

cd ninghao.net

然后执行初始化项目的命令:

vagrant init chef/centos-6.5

上面的命令就是使用之前我们下载并添加的 chef/centos-6.5 这个 box 去初始化一下项目,也就是,我们的项目会运行在 centos 6.5 这个版本的操作系统的虚拟机上。

执行了上面这行命令,会在项目的目录里面,生成一个叫 Vagrantfile 的文件,这个文件告诉了 vagrant 怎么样去运行这个虚拟机。

配置网络

如果你想让你的电脑跟虚拟机之间可以相互通信,比如你在虚拟机上安装了一个 Web 服务器,你打算可以在本地电脑上,或者同一网络内的其它设备可以访问到这台虚拟机上的项目。这需要去做一些配置,有三种方式,端口转发(Forwarded Ports),私有网络(Private Network),公有网络(Public Network)。

下面,我们去配置一个公有网络,也就是,你可以在自己的电脑上通过一个内部的 ip 地址访问到虚拟机,在同一网络内的其它设备,也可以访问到这台虚拟机。

先打开项目目录下面的 Vagrantfile 文件。找到这行代码:

# config.vm.network "public_network"

去掉它前面的 # 号:

config.vm.network "public_network"

保存文件。

启动

配置好网络以后,就可以去启动虚拟机了,确定当前所在的目录是项目的目录,然后执行:

vagrant up

返回:

Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'chef/centos-6.5'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'chef/centos-6.5' is up to date...
==> default: Setting the name of the VM: ninghaonet_default_1404827171486_40050
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Available bridged network interfaces:
1) en1: Wi-Fi (AirPort)
2) en0: 以太网
3) en4: Thunderbolt 1
4) en3: Thunderbolt 2
5) p2p0
6) bridge0
    default: What interface should the network bridge to? 

配置好网络以后,第一次启动,会出现上面这样的提示,让我们选择桥接的方式,选择哪个要看你的网络环境。比如我的电脑是在一个小型的局域网里,通过一个无线的路由器上网,所以这里,我选择第一个选项:en1:Wi-Fi(Airport)。输入数字 1,然后按下回车。

==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: bridged
==> default: Forwarding ports...
    default: 22 => 2200 (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2200
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Users/xiaoxue/Desktop/ninghao.net

ssh

启动以后,我们就可以 ssh 到虚拟机上了。使用命令:

vagrant ssh

这样就可以像操作一般的 Linux 服务器那样,去安装软件,配置等等。宁皓网的《CentOS:在阿里云上运行网站》可以帮助你理解 Linux 系统的基本操作。

注意,在你电脑上的项目的目录,与虚拟机里面的 /vagrant 这个目录是同步的。

安装 nginx

下面,我们在虚拟机上安装一下 nginx 这个 Web 服务器作为演示。在 CentOS 系统上配置一个完整的可以运行 php 的环境,可以参考这篇关于配置阿里云服务器的文章。

wget http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm

再执行:

sudo rpm -ivh nginx-release-centos-6-0.el6.ngx.noarch.rpm

然后用 yum 安装 nginx :

sudo yum install nginx

安装完成以后,可以启动 nginx 服务:

sudo service nginx start

启动了虚拟机上的 nginx 服务以后,在我们的电脑上,或者处在同一网络中的其它设备,就可以访问到这台虚拟机提供的 Web 服务了。不过,首先我们要知道这台虚拟机在内网中的 IP 地址,执行命令:

ifconfig

返回:

eth0      Link encap:Ethernet  HWaddr 08:00:27:CE:08:3D  
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fece:83d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:596 errors:0 dropped:0 overruns:0 frame:0
          TX packets:397 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:61284 (59.8 KiB)  TX bytes:50362 (49.1 KiB)

eth1      Link encap:Ethernet  HWaddr 08:00:27:C4:AB:A1  
          inet addr:192.168.1.104  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fec4:aba1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:11 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1180 (1.1 KiB)  TX bytes:1578 (1.5 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

我的电脑在这个局域网里有一个内部的 IP 地址,这个地址是 192.168.1.* ,在这个网络里面的其它的设备,比如 iPhone ,iPad 或者是其它的电脑,它们的内部的 IP 地址都是这样的形式。所以,我可以判断出,eth1 里面的 192.168.1.104 ,应该就是这台虚拟机在内网中的 IP 地址。

在自己的电脑上,打开浏览器,输入 http://192.168.1.104,你应该可以访问到虚拟机提供的 Web 服务。

命令

关掉虚拟机:

vagrant halt

重启虚拟机:

vagrant reload

销毁虚拟机:

vagrant destroy

详细的使用说明,可以查看 vagrant 官方的文档

更新

2014.07.11

今天跟大伙一起在 qq 群里,测试了一下在 Windows 下面去安装配置 vagrant。我自己也在虚拟机上安装的 Windows 做了测试。大部人都配置成功了,下面总结一下常见的问题。

在为 vagrant 添加 box 的时候,注意系统的版本。如果你的操作系统是 32 位的,那么,你下载的 box 一定也要是 32 位的,在VagrantCloud 上搜索你想要的 box ,然后选择合适的版本。比如这篇文章里我推荐安装的是 chef/centos-6.5 这个 box ,它就是一个 64 位的系统 。如果你需要 32 位的系统,可以试一下 vagrant init rafacas/centos65-i386-plain 。

在使用 vagrant up ,启动以后,使用 ssh 连接到虚拟机,Windows 用户可以使用 putty ,主机填写 127.0.0.1,端口号是 2222 ,登录的用户名是 vagrant ,密码也是 vagrant 。

在用 vagrant package 打包正在运行的 box 以后,可以添加这个 box ,用 vagrant box add 命令。下次再 init 项目的时候,就可以使用这个 box 了 。在启动的时候,可能会遇到问题,我遇到的问题是由网卡引起的,解决的方法是删除 /etc/udev/rules.d/70-persistent-net.rules 。

2014.08.04

今天发现 nginx 服务器不能同步在本地编辑的静态文件,解决的办法是,编辑 nginx 的配置文件,在 server 或 location 区块里面,添加 sendfile off;