Devil May Code...

Vergil's Blog

前言

虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。

使用虚拟机搭建本地开发环境,安全地与本地操作系统隔离开,让开发环境和生产环境保持一致。

使用Windows系统开发PHP的小伙伴们,更加强烈推荐使用虚拟机的开发环境:

  • Windows大小写不敏感,很容易因为这个问题出现错误而无法得知
  • 很多软件只有Linux版,或者Windows版本不完善(例如Nngix,Memcached,Redis)
  • 部分扩展模块不支持(如memcached,pcntl,ZendOpcache, swoole
  • 大部分的PHP生产环境都运行在Linux上,保证代码兼容性

安装VirtualBox

VartualBox是一款优秀的虚拟机软件,现有Oracle公司进行开发。它提供用户在32位或64位的Windows、Solaris、MacOS及Linux 操作系统上虚拟其它x86的操作系统。

进入VartualBox下载页面选择合适的版本下载并按提示进行安装。

Vagrant

什么是Vagrant

Vagrant是一款用于构建及配置虚拟开发环境的软件,基于Ruby,主要以命令行的方式运行。

主要使用Oracle的开源VirtualBox虚拟化系统,与Chef,Salt,Puppet等环境配置管理软件搭配使用, 可以实行快速虚拟开发环境的构建。

早期以VirtualBox为对象,1.1以后的版本中开始对应VMware等虚拟化软件,包括Amazon EC2之类服务器环境的对应。

安装Vagrant

Vagrant支持MacOS、Windows、Linux多种操作系统。进入下载页面下载适合你操作系统的安装程序进行安装。

Vagrant镜像

Vagrant环境的虚拟机镜像称为box。在Vargrant官网中有一个Boxes链接到HashiCorp's Atlas。这个是Vargrant的boxes仓库。

Vargrant是一款命令行工具,它与Atlas的关系相当于Composer之于Packagistbox就相当于packagist里面的package。

另外,还有另外一个第三方boxes仓库:http://www.vagrantbox.es/

添加box

在Atlas找到合适你的系统box和版本。在本例中,我尝试找Ubuntu这个优秀的Linux发行版。搜索ubuntu关键字,可以得到很多不同作者或不同的版本,当前最新的LTS版是1604,它在Atlas的名字叫做ubuntu/xenial64

Vagrant的每个命令或子命令都可以加入参数-h--help获得帮助。

使用vagrant box add命令添加box:

$ vagrant box add ubuntu/xenial64
==> box: Loading metadata for box 'ubuntu/xenial64'
    box: URL: https://atlas.hashicorp.com/ubuntu/xenial64
==> box: Adding box 'ubuntu/xenial64' (v20161221.0.0) for provider: virtualbox
    box: Downloading: https://atlas.hashicorp.com/ubuntu/boxes/xenial64/versions/20161221.0.0/providers/virtualbox.box
==> box: Box download is resuming from prior download progress
    box: Progress: 0% (Rate: 33071/s, Estimated time remaining: 4:40:52)

输入命令后,你会看到类似的命令行提示,表示说Vagrant正在从远程的地址下载这个box。

这是一个漫长的过程,如果你的下载速度不是太理想,建议按CTRL+C取消命令行下载。从命令行提示得知,它的下载地址是https://atlas.hashicorp.com/ubuntu/boxes/xenial64/versions/20161221.0.0/providers/virtualbox.box,你可以复制这个地址然后使用迅雷等多线程下载工具把box下载到本地。

$ vagrant box add ubuntu/xenial64 ~/Downloads/ubuntu-xenial64.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'ubuntu/xenial64' (v0) for provider:
    box: Unpacking necessary files from: file:///Users/vergil/Downloads/ubuntu-xenial64.box
==> box: Successfully added box 'ubuntu/xenial64' (v0) for 'virtualbox'!

使用list子命令可以查看所有已安装的box

$ vagrant box list
ubuntu/xenial64 (virtualbox, 0)

使用remove子命令可以移除一个已添加的box

$ vagrant box remove ubuntu/xenial64

配置和创建虚拟机

首先,创建一个新的空目录并进入

$ mkdir ~/vagrant_demo
$ cd ~/vagrant_demo

使用vagrant init命令,在当前目录创建Vagrantfile

$ vagrant init

或者指定虚拟机使用的box:

$ vagrant init ubuntu/xenial64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

Vagrantfile的主要功能是描述你需要的虚拟机类型,以及如何配置这些虚拟机。类似于Composercomposer.json文件。

Vagrantfile

Vagrant每个虚拟机都需要运行Vagrantfile。Vagrantfile使用Ruby的语法编写,即使不懂Ruby语言也可以轻松的编辑Vagrantfile,因为它主要是简单的变量赋值。

这里简单说几个重要的配置。

使用你喜欢的文本编辑器打开Vagrantfile,可以看到,它只有短短几行(#号开头的行是注释)。

Vagrant.configure("2") do |config|
  # v2 configs...
end

第一行中的2表示vagrant的版本,目前只支持12。版本1表示Vagrant 1.0.x的配置。2表示Vagrant 1.1+版本的配置。虚拟机的详细配置在关键字doend之间。用vagrant init命令生成的Vagrantfile不需要修改这个版本号,如果用别人共享的Vagrantfile文件的话需要留意下是否适合你的Vagrant版本。

config.vm.box

config.vm.box = "ubuntu/xenial64"

config.vm.box这个配置是描述虚拟机将要使用的镜像box。这里的值应该HashiCorp's Atlas列出的box名称,或者已安装(使用vagrant box add命令添加)的box名称。

目前它自动填上值ubuntu/xenial64,那是因为我使用vagrant init ubuntu/xenial64时指定了box名称。

config.vm.hostname

config.vm.hostname定义虚拟机的主机名。如:

config.vm.hostname = "vm.vergil.cn"

config.vm.network

config.vm.network配置虚拟机的网络。Vagrant提供3种网络设置:

  • 端口转发(forwarded_port)

    可以看到自动生成的Vagrantfile里面有这句被注释掉的:

      config.vm.network "forwarded_port", guest: 80, host: 8080
    

    它的意思是转发本机(客户机)的80端口映射到虚拟机的8080端口。

    默认它定义为TCP协议,你可以使用第三个参数protocol指定转发端口的协议:可用的值tcp,udp,tcp/udp 如:

      config.vm.network "forwarded_port", guest: 2003, host: 12003, protocol: "tcp/udp"
    
  • 公共网络(public_network)

    • 使用config.vm.network "public_network"语句来指定使用公共网络。

    • 可以添加参数来指定它使用DHCP自动分配:
      config.vm.network "public_network",use_dhcp_assigned_default_route: true

    • 也可以指定静态IP地址:
      config.vm.network "public_network", ip: "192.168.0.17"

    • 指定网卡,可以用过:dridge选项
      config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"

  • 专用网络(private_network)

    • 定义DHCP专用网络
      config.vm.network "private_network", type: "dhcp"

    • 指定IP:
      config.vm.network "private_network", ip: "192.168.50.4"

config.vm.synced_folder

config.vm.synced_folder配置项用来配置同步文件夹。就是把本地目录和文件挂载到虚拟机上。

第一个参数是你本机的文件夹路径,可以是绝对路径或相对路径(相对于项目根目录,也就是创建虚拟机时,Vagrantfile所在的目录)。

第二个参数是虚拟机的目录,必须是一个绝对路径。如果不存在会被自动创建。

其他参数请参阅文档

如:

config.vm.synced_folder "/data/htdocs", "/wwwroot"

在默认情况下,如果缺省这个参数,Vagrant会将项目目录共享到虚拟机的/vagrant目录

config.vm.provider

config.vm.provider配置项用于配置指定的虚拟机和对于不同的虚拟机软件的特定设置。默认情况下会指定virtualbox

在自动生成的Vagrant,可以看到以下被注释的语句,这个是对virtualbox的配置例子:

  # config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  

这里我简单介绍几个常用配置:

  • gui

    默认情况下,VirtualBox以headless mode(无外设模式)启动,意味着没有GUI。如果你想看到虚拟机的UI,可以将它设为true:

      vb.gui = true
    
  • name

    这个配置项用于设置VirtualBox管理器上显示的名称,如果有多台虚拟机以便更好的区分

  • customize

    VBoxManage工具可以从命令行对VirtualBox进行修改。Vagrant提供一种方法在虚拟机启动前调用VBoxManage命令:

      vb.customize ["modifyvm", :id, "--memory", "1024", "--cpus", "1"]
      
    

    有一些方便的快捷方式用于内存和CPU设置:

      vb.memory = 1024
      vb.cpus = 2
      
    

创建虚拟机

OK,修改后,我的Vagrantfile如下:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
  config.vm.network "private_network", ip: "192.168.10.10"
  config.vm.synced_folder "./data", "/vagrant_data"
  config.vm.synced_folder "/data/htdocs/", "/wwwroot"

  config.vm.provider "virtualbox" do |vb|
     vb.gui = true
     vb.name = "ubuntu1604"
     vb.memory = "1024"
   end
end

此时,在你Vargrant所在的目录,运行命令vagrant up。这个命令根据你的Vagrantfile创建和配置虚拟机。而当前目录也是上面提到的项目根目录。

$ pwd
/Users/vergil/Documents/vagrant_demo

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu/xenial64'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: ubuntu1604
==> default: Fixed port collision for 22 => 2222. Now on port 2201.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 (guest) => 2201 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2201
    default: SSH username: ubuntu
    default: SSH auth method: password
    default: Warning: Remote connection disconnect. Retrying...
    default:
    default: Inserting generated public key within guest...
    default: Removing insecure key from the guest if it's present...
    default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> 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/vergil/Documents/vagrant_demo
    default: /wwwroot => /data/htdocs
    default: /vagrant_data => /Users/vergil/Documents/vagrant_demo

这时,虚拟机创建成功并启动了!因为我设置了gui=true,所以打开VirtualBox同时启动了:

1.png

使用其他虚拟机软件

Vagrant大部分的box都支持VirtualBox,如果你使用的是其他虚拟机软件,需要查看它是否支持。也可以在HashiCorp's Atlas页面的Provider filter筛选你所使用的虚拟机软件。

然后在vagrant up提供参数--provider,比如CentOS7VMware Workstation上运行:

vagrant init centos/7; 
vagrant up --provider vmware_workstation

查看虚拟机状态

使用vagrant status命令可以查看当前项目目录的虚拟机状态:

$ vagrant status
Current machine states:

default                   running (virtualbox)

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.

离开项目目录使用status是不能的,如果想查看全局所有的虚拟机状态,可以使用global-status命令:

$ vagrant global-status
id       name        provider   state    directory
--------------------------------------------------------------------------------
c2fdbe7  homestead-7 virtualbox poweroff /Users/vergil/Homestead
6e85c79  machine1    virtualbox running  /Users/vergil/Documents/puphpet/2UQFc8
9b77363  default     virtualbox running  /Users/vergil/Documents/vagrant_demo

The above shows information about all known Vagrant environments
on this machine. This data is cached and may not be completely
up-to-date. To interact with any of the machines, you can go to
that directory and run Vagrant, or you can use the ID directly
with Vagrant commands from any directory. For example:
"vagrant destroy 1a2b3c4d"

关闭/启动/重启/暂停/恢复/销毁虚拟机

以下命令可以在项目目录直接运行,如果在非项目目录下需要指定虚拟机的idname

可以在项目目录运行vagrant halt关闭当前项目虚拟机,如果在非项目目录虚拟指定虚拟机的idname关闭虚拟机,如:

$ vagrant halt 9b77363

vagrant up启动虚拟机:

$ vagrant up

vagrant reload相当于halt之后up,并且对Vagrantfile中的更新生效。。

$ vagrant reload

使用过VirtualBox的同学(包括我)都不会直接关闭虚拟机,而是让它暂停(休眠),Vagrant同样有这样的功能:

$ vagrant suspend

然后在你需要的时候把它唤醒

$ vagrant resume

使用SSH连接到虚拟机

使用vagrant ssh命令可以在项目目录通过SSH方式连接到虚拟机,或者指定虚拟机idname

vagrant ssh 9b77363
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-57-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

0 packages can be updated.
0 updates are security updates.


Last login: Sun Jan  1 20:17:54 2017 from 10.0.2.2
ubuntu@ubuntu-xenial:~$

ok,看到这些信息已经成功连接到虚拟机啦。试试运行下面命令?

ubuntu@ubuntu-xenial:~$ hostname
ubuntu-xenial
ubuntu@ubuntu-xenial:~$ ifconfig
enp0s3    Link encap:Ethernet  HWaddr 02:a6:9f:fe:ad:64
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::a6:9fff:fefe:ad64/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1078 errors:0 dropped:0 overruns:0 frame:0
          TX packets:751 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:120599 (120.5 KB)  TX bytes:102761 (102.7 KB)

enp0s8    Link encap:Ethernet  HWaddr 08:00:27:62:bc:20
          inet addr:192.168.10.10  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fe62:bc20/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:1296 (1.2 KB)

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:65536  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:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ubuntu@ubuntu-xenial:~$ whoami
ubuntu
ubuntu@ubuntu-xenial:~$ sudo passwd ubuntu
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
ubuntu@ubuntu-xenial:~$

在这里,我知道了当前的用户名是ubuntu,并且我重置了密码:)

从其他终端连接

很多人(特别是Windows用户)喜欢从其他终端登录,如:PuTTYSecureCRT®

从上面运行vagrant up后输出的信息可以看到,Vagrant把虚拟机的22端口映射到了本机(宿主机)的2201端口。

注意:默认情况下,它会映射到2222端口,但是我有其他虚拟机并且启动了,所以该端口被占用

使用vagrant ssh-config查看虚拟机的SSH配置:

$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User ubuntu
  Port 2201
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/vergil/Documents/vagrant_demo/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

那么,可以在使用宿主机的命令或工具(我这里没有安装其他Shell客户端工具)连接到虚拟机:

ssh -p 2201 ubuntu@127.0.0.1
ubuntu@127.0.0.1's password:
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-57-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

0 packages can be updated.
0 updates are security updates.


Last login: Sun Jan  1 20:23:14 2017 from 10.0.2.2
ubuntu@ubuntu-xenial:~$ exit
logout
Connection to 127.0.0.1 closed.

或者直接使用IP登录更为省事:

ssh ubuntu@192.168.10.10
ubuntu@192.168.10.10's password:
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-57-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  Get cloud support with Ubuntu Advantage Cloud Guest:
    http://www.ubuntu.com/business/services/cloud

0 packages can be updated.
0 updates are security updates.


Last login: Sun Jan  1 20:29:14 2017 from 10.0.2.2
ubuntu@ubuntu-xenial:~$ exit
logout
Connection to 192.168.10.10 closed.

查看共享文件夹

在虚拟机终端内,查看我刚才在Vagrantfile写的/vagrant_data/wwwroot目录,你可以发现里面的文件和你宿主机的文件是同步的。

查看文件系统:

$ df -hT
Filesystem     Type      Size  Used Avail Use% Mounted on
udev           devtmpfs  490M     0  490M   0% /dev
tmpfs          tmpfs     100M  3.1M   97M   4% /run
/dev/sda1      ext4      9.7G  918M  8.8G  10% /
tmpfs          tmpfs     497M     0  497M   0% /dev/shm
tmpfs          tmpfs     5.0M     0  5.0M   0% /run/lock
tmpfs          tmpfs     497M     0  497M   0% /sys/fs/cgroup
vagrant        vboxsf    233G  204G   30G  88% /vagrant
wwwroot        vboxsf    233G  204G   30G  88% /wwwroot
vagrant_data   vboxsf    233G  204G   30G  88% /vagrant_data
tmpfs          tmpfs     100M     0  100M   0% /run/user/1000

打包

这时,已经安装好了操作系统,然后你需要在这上面搭建你的开发环境。

一切正常工作后,你是否想将这个环境复用或者分享给同事,使大家的开发环境一致呢?

在宿主机上运行vagrant package命令,可以将当前运行的VritualBox环境打包成可重用的box.

$ vagrant package --base ubuntu1604 --output ~/Documents/vagrant_demo/package/vergil_ubuntu1604.box
==> ubuntu1604: Attempting graceful shutdown of VM...
    ubuntu1604: Guest communication could not be established! This is usually because
    ubuntu1604: SSH is not running, the authentication information was changed,
    ubuntu1604: or some other networking issue. Vagrant will force halt, if
    ubuntu1604: capable.
==> ubuntu1604: Forcing shutdown of VM...
==> ubuntu1604: Clearing any previously set forwarded ports...
==> ubuntu1604: Exporting VM...
==> ubuntu1604: Compressing package to: /Users/vergil/Documents/vagrant_demo/package/vergil_ubuntu1604.box

成功后查看一下:

$ du -sh ~/Documents/vagrant_demo/package/vergil_ubuntu1604.box
287M    /Users/vergil/Documents/vagrant_demo/package/vergil_ubuntu1604.box

配置多台虚拟机

Vagrant配置多台虚拟机实现分布式效果也非常方便的。

多个机器在同一个项目的Vagrantfile中,使用config.vm.define方法定义机器。然后配置每个机器的信息:

一个简单的例子:

Vagrant.configure("2") do |config|

  config.vm.define "web1" do |web1|
     web1.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--name", "web1", "--memory", "1024"]
     end
    web1.vm.box = "your-apache.box"
    web1.vm.hostname = "web1"
    web1.vm.network "public_network", ip: "192.168.31.101"
  end
  
  config.vm.define "web2" do |web2|
    web2.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--name", "web2", "--memory", "1024"]
     end
    web2.vm.box = "your-apache.box"
    web2.vm.hostname = "web2"
    web2.vm.network "public_network", ip: "192.168.31.102"
  end

  config.vm.define "db1" do |db1|
     db1.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--name", "db1", "--memory", "1024"]
     end
    db1.vm.box = "your-mysql.box"
    db1.vm.hostname = "db1"
    db1.vm.network "public_network", ip: "192.168.31.201"
  end
  
  config.vm.define "db2" do |db2|
    db2.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--name", "db2", "--memory", "1024"]
     end
    db2.vm.box = "your-mysql.box"
    db2.vm.hostname = "db2"
    db2.vm.network "public_network", ip: "192.168.31.202"
  end
end

PROVISIONING

那么,看了半天,还要自己手动搭建开发环境啊?

很遗憾,是的。但请接着看下面的。

通常情况下Box只做最基本的设置,而不是设置好所有的环境,因此Vagrant通常使用Chef或者Puppet来做进一步的环境搭建。

自动配置虚拟机

Puppet

puppet是一种Linux、Unix、windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件、用户、cron任务、软件包、系统服务等。puppet把这些系统实体称之为资源,puppet的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。

PuPHPet

学习puppet成本高,还要学一套它的理论和它的语法,现在使用它并不能马上让你搭建一个开发环境。

PuPHPet是一个简单的设置Web开发虚拟机的GUI。

  • 轻松地与朋友和同事分享
  • 部署到世界上任何的服务器
  • MIT开源协议

2.png

PuPHPet,通过简单的设置,你可以选择把虚拟机配置到哪里,可以选择你想要的操作系统,选择你喜欢的PHP版本,选择数据库和版本,还有其他软件等等。。。然后PuPPet会帮你生成一个Vagrantfile文件和Puppet配置,下载解压后,你要做的事情就是运行vagrant up,它就会完成你的要求,帮你自动配置你的虚拟机啦(期间内我个人建议可以去睡觉了)。

在左边的导航栏,你可以看到这些选项

  • Deploy Target

    点击Deploy Target下的Locally。然后把Deploy to Local Host(部署到本机)前面的勾打上。

    然后选择你的虚拟机软件,系统发行版,添加你的机器信息(包括机器名称,Hostname,IP,内存,CPU,端口转发,共享文件夹等等)。

    它还可以同时配置多台机器,点击Add another machine继续填写信息即可。

  • System

    • Packages: 添加你想要的系统软件
    • User & Groups: 设置用户和用户组
    • Locate/Timezone: 设置系统默认语言和支持的语言,时区
    • Firewall Rules:防火墙规则
    • Cron Jobs:添加计划任务
  • Web Servers

    设置Web服务器,默认Nginx。详细参数查看Nginx官方文档或者淘宝提供的中文版本

    当然,你也可以选择Apache或者Nginx和Apache配合使用搭建LNAMP环境。

  • Languages

    选择开发语言(默认PHP),其他的还有Ruby,Python,NodeJS,还有PHP的HHVM

    选择PHP的版本,是否安装Composer,php.ini的设置,FastCGI参数的设置,需要安装什么模块。都可以在这里设置

  • Databases

    选择数据库和版本(默认MaridDB),创建用户密码和权限,都在这里设置。

    支持的数据库:

    • MariaDB
    • MySQL
    • PostageSQL
    • MongoDB
    • Redis
    • SQLite

Create Archive

上述步骤完成后,点击Create Archive页面的Download your custom server config!,PuPHPet会根据你的选择创建Vagrantfile文件和puppet的配置文件的压缩包puphpet.zip

3.png

解压后,进入到Vagrantfile所在目录,运行vagrant up,它就会自动配置你的虚拟机了。

稍等,在运行之前,你可以安装一个Vagrant插件host manager,这个插件让Vagrant会自动把你设置的主机名添加到/ect/hosts

$ vagrant plugin install vagrant-hostmanager
Installing the 'vagrant-hostmanager' plugin. This can take a few minutes...
Installed the plugin 'vagrant-hostmanager (1.8.5)'!

当然你可以跳过这一步,那么开始了:

$ vagrant up

4.png

ZZZZzzzz。。。。

ZZZZzzzz。。。。

ZZZZzzzz。。。。

ZZZZzzzz。。。。

安装完成后,检查各个软件都能工作正常了,就可以再次用上面说到的vagrant package命令把这个环境打包成一个box共享给你的小伙伴使用啦:)

Laravel Homestead

可能看到这里的小伙伴们有点不耐烦了,要么要自己配置,要么就是等待这么漫长的时间。那有没有一个拆箱即用的开发环境呢?

有的,那就是Laravel Homestead

如果看了文章前面的内容的话,就算没接触过Laravel,也会觉得这个名字很熟?

没错,它就是在HashiCorp's Atlas下载量非常高的一个box

5.png

  • GitHub: https://github.com/laravel/homestead
  • Atlas: https://atlas.hashicorp.com/laravel/boxes/homestead
  • Packagest: https://packagist.org/packages/laravel/homestead

简介

Laravel 致力于让 PHP 的开发过程变得更加轻松愉快,这其中也包含你的本地开发环境。

Laravel Homestead 是一个官方预封装的 Vagrant box,提供给你一个完美的开发环境,你无需在本机电脑上安装 PHP、HHVM、Web 服务器或其它服务器软件。并且不用再担心系统被搞乱!Vagrant box 为你搞定一切。如果有什么地方出错了,你也可以在几分钟内快速的销毁并重建虚拟机!

Homestead 可以在 Windows、Mac 或 Linux 系统上面运行,里面包含了 Nginx Web 服务器、PHP 7.0、MySQL、Postgres、Redis、Memcached、Node,以及所有你在使用 Laravel 开发时所需要用到的各种软件。

Laravel是一款非常非常...(这里省略1万字)好用的PHP框架。但是Homestead只是一个开发环境,就算你不用Laravel框架也可以用Homestead,也是非常好用的哦(就是感觉内置软件有点多了。。。)

内置软件

  • Ubuntu 16.04
  • Git
  • PHP 7.0
  • Nginx
  • MySQL
  • MariaDB
  • Sqlite3
  • Postgres
  • Composer
  • Node (With PM2, Bower, Grunt, and Gulp)
  • Redis
  • Memcached
  • Beanstalkd

安装

好了,复制官方手册也没意思,建议去Laravel China看下中文文档。

那么我就重新安装一下吧,首先,你要确保已经安装了Composer(现代PHP必装工具),确保composer目录已经添加到系统环境变量。

然后全局安装laravel/homestead

$ composer global require laravel/homestead

安装安装后可以发现~/.composer/vendor/bin(Linux/OS X用户), Windows用户在C:/Users/{用户名}/AppData/Roaming/Composer/vendor/bin)目录下,然后把这个目录添加到环境变量。

添加box

首先添加一个box,这一步可以省略,因为运行vagrant up时发现你没有这个box,它会自动下载,只是这样更加快一点(这个box很大呐,1.03G)。

$ vagrant box add laravel/homestead --provider virtualbox
==> box: Loading metadata for box 'laravel/homestead'
box: URL: https://atlas.hashicorp.com/laravel/homestead
==> box: Adding box 'laravel/homestead' (v1.0.1) for provider: virtualbox
    box: Downloading: https://atlas.hashicorp.com/laravel/boxes/homestead/versions/1.0.1/providers/virtualbox.box
    box: Progress: 0% (Rate: 24507/s, Estimated time remaining: 17:34:52)
    
    

看到这个之后,按CTRL+C取消,复制地址,然后用迅雷下载。

6.png

下载完成后,运行以下命令添加本地box,请按你刚才下载的box文件所在路径修改第二个参数:

$ vagrant box add laravel/homestead ~/Downloads/homestead.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'laravel/homestead' (v0) for provider:
    box: Unpacking necessary files from: file:///Users/vergil/Downloads/homestead.box
==> box: Successfully added box 'laravel/homestead' (v0) for 'virtualbox'!
$ vagrant box list
laravel/homestead      (virtualbox, 0)
puphpet/ubuntu1604-x64 (virtualbox, 20161102)
ubuntu/xenial64        (virtualbox, 0)

创建配置文件

然后创建一个新的目录,进入并运行homestead make

$ homestead -V
Laravel Homestead version 4.0.2
$ mkdir ~/Documents/homestead_demo
$ cd ~/Documents/homestead_demo
$ homestead make
Homestead Installed!
$ ls
Homestead.yaml Vagrantfile

你会发现homestead帮你创建了Vagrantfile和一个Homestead.yaml文件(YAML语法,很简单,看下就懂)

大概阅读一下Vagrantfile文件内容,它大概描述的事情就是:

定义一些文件名称,如果存在这个文件,就做一些事情:

  • Homestead.yaml

    定义一些配置,然后它会把yaml的文件当参数传递给脚本主文件/scripts/homestead.rb

  • Homestead.json

    配置文件的JSON描述,有Homestead.yaml即可

  • after.sh

    shell脚本。

    如果存在这个文件,它将会传递给Vagrantfileconfig.vm.provider配置项,Vagrant运行虚拟机之后会运行该脚本。

  • aliases

    Bash Shell 的别名设置。
    如果存在这个文件,它将会进行别名设置。

值得注意的是,在第8行的位置:

confDir = $confDir ||= File.expand_path("vendor/laravel/homestead", File.dirname(__FILE__))

在当前文件所在目录的位置的vendor/laravel/homestead定义一个配置脚本的目录,然而我是composer global require的,当前位置并没有这个目录,那么有两种方法修改:

  • Windows用户修改为: confDir = "C:/Users/{用户名}/AppData/Roaming/Composer/vendor/laravel/homestead"

    OS X或Linux用户修改为: confDir = "~/.composer/vendor/laravel/homestead"

  • OS X或Linux用户可以使用软链接

      $ ln -s ~/.composer/vendor ./
    

修改Homestead.yaml

详细请参考Laravel China文档,配置 Homestead章节:https://laravel-china.org/docs/5.3/homestead#配置-Homestead

注意!

值得注意的是:因为我刚才是下载box文件然后本地添加box,所以这个box没有版本号。

但是Homestead脚本文件homestead.rb,第18行写道:

config.vm.box_version = settings["version"] ||= ">= 1.0.0"

意思是你的Homestead.yaml没有定义version这个变量,那么它默认为>= 1.0.0这个版本的box。那么它会重新下载box的。

所以,在Homestead.yaml添加一行:

version: "0"

启动虚拟机

运行命令启动虚拟机:

$ vagrant up
Bringing machine 'homestead-demo' up with 'virtualbox' provider...
==> homestead-demo: Importing base box 'laravel/homestead'...
==> homestead-demo: Matching MAC address for NAT networking...
==> homestead-demo: Setting the name of the VM: homestead-demo
==> homestead-demo: Clearing any previously set network interfaces...
==> homestead-demo: Preparing network interfaces based on configuration...
    homestead-demo: Adapter 1: nat
    homestead-demo: Adapter 2: hostonly
==> homestead-demo: Forwarding ports...
    homestead-demo: 80 (guest) => 8000 (host) (adapter 1)
    homestead-demo: 443 (guest) => 44300 (host) (adapter 1)
    homestead-demo: 3306 (guest) => 33060 (host) (adapter 1)
    homestead-demo: 5432 (guest) => 54320 (host) (adapter 1)
    homestead-demo: 22 (guest) => 2222 (host) (adapter 1)
==> homestead-demo: Running 'pre-boot' VM customizations...
==> homestead-demo: Booting VM...
==> homestead-demo: Waiting for machine to boot. This may take a few minutes...
    homestead-demo: SSH address: 127.0.0.1:2222
    homestead-demo: SSH username: vagrant
    homestead-demo: SSH auth method: private key
    homestead-demo:
    homestead-demo: Vagrant insecure key detected. Vagrant will automatically replace
    homestead-demo: this with a newly generated keypair for better security.
    homestead-demo:
    homestead-demo: Inserting generated public key within guest...
    homestead-demo: Removing insecure key from the guest if it's present...
    homestead-demo: Key inserted! Disconnecting and reconnecting using new SSH key...
==> homestead-demo: Machine booted and ready!
==> homestead-demo: Checking for guest additions in VM...
==> homestead-demo: Setting hostname...
==> homestead-demo: Configuring and enabling network interfaces...
==> homestead-demo: Mounting shared folders...
    homestead-demo: /vagrant => /Users/vergil/Documents/homestead_demo
    homestead-demo: /home/vagrant/homestead-demo => /data/htdocs
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: inline script
==> homestead-demo:
==> homestead-demo: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMVTf0+PAswPuzYZ2Z4og5E3A+OhDPaMLsUsLGYhGxQ97z8wK86TtVsaqkDYEqxxjgd61uVW7My+2i31x46q3K+XUVBDMI9lGuRC+iep8B4IFNtyCxQnzKEvplILd3Q0VGOJawVAo+pv+nZNfhL6apcvurK6bboFzROPbrBQA+rLHze6QzkJ+MNebWSGk6xMlvrXiBPiYOZx6+47oeHEHszbNLhgg82K330JpkRZF3gJG/iyMxIyQqlsw0ilL6Z+G68CjnYAu1Tbt5BFlMZLRbmPuxfbtlxK05fqHgJK9XPGyV8uKyhPV7afQFxNIzetbfLnMFCnkPpZ3Ac6MrJ83b vergil@homestead
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: inline script
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: /var/folders/kg/r_jt8f2s6t94xpjq6175cywm0000gn/T/vagrant-shell20170102-54691-1dq2pbo.sh
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: script: Creating Site: homestead.app
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: script: Restarting Nginx
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: script: Creating MySQL Database
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: script: Creating Postgres Database
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: script: Clear Variables
==> homestead-demo: Running provisioner: shell...
    homestead-demo: Running: script: Update Composer
==> homestead-demo: Updating to version 1.3.0 (stable channel).
==> homestead-demo:     Downloading: Connecting...
==> homestead-demo:
==> homestead-demo:     Downloading: 100%
==> homestead-demo:
==> homestead-demo:
==> homestead-demo: Use composer self-update --rollback to return to version 1.2.3

OK,从上面的信息可以看到,虚拟机创建成功,然而后面有些红色的失败信息。那是因为它的有脚本需要运行composer self-update来更新Composer。我这里没有配置公共网络,有需要的配置一下就好了。

现在看一下虚拟机的信息:

$ vagrant global-status
id       name           provider   state    directory
-----------------------------------------------------------------------------------
6e85c79  machine1       virtualbox poweroff /Users/vergil/Documents/puphpet/2UQFc8
9b77363  default        virtualbox poweroff /Users/vergil/Documents/vagrant_demo
75df57a  homestead-demo virtualbox running  /Users/vergil/Documents/homestead_demo

The above shows information about all known Vagrant environments
on this machine. This data is cached and may not be completely
up-to-date. To interact with any of the machines, you can go to
that directory and run Vagrant, or you can use the ID directly
with Vagrant commands from any directory. For example:
"vagrant destroy 1a2b3c4d"

尝试ssh连接和vagrant ssh连接,用户名和密码都是:vagrant

$ ssh vagrant@192.168.10.100
The authenticity of host '192.168.10.100 (192.168.10.100)' can't be established.
ECDSA key fingerprint is SHA256:RI5/3ep65qXeDkZSACi/rN0hBxiLrBxMvcyk9CfLkyg.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.10.100' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-51-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

3 packages can be updated.
0 updates are security updates.


Last login: Mon Jan  2 14:10:51 2017 from 10.0.2.2
vagrant@homestead-demo:~$ exit
logout
Connection to 192.168.10.100 closed.

$ vagrant ssh
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-51-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

3 packages can be updated.
0 updates are security updates.


Last login: Mon Jan  2 14:11:48 2017 from 192.168.10.1
vagrant@homestead-demo:~$ exit
logout
Connection to 127.0.0.1 closed.

连接没有问题,在/ect/hosts(Windows用户在C:/Windows/System32/drivers/etc/hosts)上加入:

192.168.10.100  http://homestead.app

然后在本机用浏览器访问http://homestead.app上的文件:

9.png

宿主机上尝试连接Homestead的MySQL:

用户名:homestead

密码:secret

$ mysql -u homestead -h 192.168.10.100 -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.16-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases\G
*************************** 1. row ***************************
Database: information_schema
*************************** 2. row ***************************
Database: homestead
*************************** 3. row ***************************
Database: mysql
*************************** 4. row ***************************
Database: performance_schema
*************************** 5. row ***************************
Database: sys
5 rows in set (0.01 sec)

mysql> exit
Bye

或者访问本机的33060端口(映射到虚拟机的3306):

$ mysql -h 127.0.0.1 -u homestead -P 33060 -psecret
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.16-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye

No problem :)

Homestead的功能部分持续更新中。。。


到此,从自己搭建虚拟机系统 —— 使用puppet配置系统 —— 使用Homestead提供的Box。你可以选择一个适合你的方式,或者自己打造一个适合你的开发团队的开发环境系统。


原创文章,转载请注明

参考资料:

Introduction to Vagrant/Puppet and introducing PuPHPet - A simple to use Vagrant/Puppet GUI Configurator!

Configuring PuPHPet for a simple LAMP setup

Laravel China


已有 2 条评论 »

  1. 又学了一招

  2. Raikinei Raikinei

    写得很好,学习了

添加新评论 »

在这里输入你的评论...

Powered by Typecho.