Vagrant-打造一份通用的前端开发环境
前言
最近在做一个项目的时候,手贱删了Ubuntu下的~/.*
的文件,好多配置文件包括.bash_profile/.bashrc/.zshrc等重要的文件全都清空了,自己一下子懵逼了,我可都是没有备份这些文件呀呀。难道我又得重新安装一遍系统吗?
无意中,听到我们组长说起Vagrant,说是搭建开发环境是分分钟的事情,并且能够一份配置能够跨平台到处使用,不禁心动起来,于是乎就立马去试试这个Vagrant了,于是有了这篇文章。
1、Vagrant是啥?
玩转一个新鲜的东西之前,我们是有必要了解这个东西是啥?翻阅了国内国外的资料,大致明白了Vagrant的基本原理了。
在平时开发的时候,我是在虚拟机的基础上运行Ubuntu,然后这个过程中你就需要安装系统,分区、选择各种软件以及卸载掉很多无关的系统自带软件,这些过程都可以参考之前写过的几篇文章(VirtualBox简单配置Ubuntu16.04、Vmware安装Ubuntu15.10),这样一套的系统完成至少得持续一个小时才能完成。最后可以移植的vmdk文件也会达到3、4G那么大。可谓是劳民伤神呀。
因此为了解决这个痛点,Vagrant应运而生。它省却了你安装系统的一切烦恼,一个box便可以解决这些问题,而且体积大大减轻,并且可以跨平台跨环境任意使用,是不是觉得很神奇呢?Vagrant的Box其实可以看成是之前你在虚拟机上安装完系统生成的Vmdk文件的一个封装(假设你的Provider是VirtualBox之类的虚拟机)
因此Vagrant可以看成是一个高级的虚拟机镜像管理器。一套完整的环境镜像称之为Box。任何人都可以制作属于自己的box。这个box就是所谓的开发环境,包含系统和相关的软件。通过vagrant方便的与虚拟机共享文件。即将宿主机的文件夹映射到虚拟机的文件系统里。还可以映射网络端口,设置通信的私有网络等。vagrant依赖与虚拟机,目前支持的虚拟化方式很多。与Virtualbox、VMware、Docker都能很好的工作。
1.1、Provider
在Vagrant看来,诸如VirtualBox这类的虚拟机都是统称为Provider
Provider 的作用是在 Vagrant 和不同虚拟化软件之间架设一座桥梁。有了 Provider,Vagrant 管理不同虚拟机软件的命令完全一致,使用更方便。现阶段的 Vagrant 不能更换已有环境的 Provider,如果你的 Vagrant 环境需要封装给其他小伙伴们用,最好使用 VirtualBox 这个支持 OSX/Linux/Win 三大宿主系统的免费软件作为后端;如果你只是自己用,并且已经装有 Parallels Desktop,那就可以使用 Parallels Provider,可以少装一个软件。顺便说下,现在 VirtualBox 和 Parallels Desktop 同时运行也没问题了。
1.2、Box
Boxes 是一个后缀为 box的文件,实际上它就是一个包含了虚拟机配置、虚拟机硬盘镜像和 Vagrant 配置的压缩包。之前在虚拟机里安装 Linux,首先需要下载 iso 安装镜像并新建虚拟机,然后修改虚拟机的 cpu、内存、光驱、网络等等硬件配置,再从光驱启动并安装虚拟机,完成后还有装虚拟机增强工具、配置系统、映射端口、映射磁盘目录等好多事要做。有了封装好的 Boxes,我们就可以快速运行所需要的操作系统了。不同 Provider 之间,Boxes 不能混用。
一个Box解压之后应该存在的文件是:
2、开始打造通用的前端开发环境
明白了Vagrant是啥,那么基于Vagrant来打造一套开发环境应该会变得有趣很多。我们不打算从头开始制作一个Box,而是使用Vagrant现有的基本Box来改造,大部分的Box可以在下面的网站上找到:
因为我一直使用的Ubuntu16,所以选择了ubuntu/xetinal16作为我们的Base Box。
2.1、下载并安装Base Box
我们首先新建一个目录:Vagrant
然后进入该目录运行如下命令:
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.
这个时候Vagrant会自动为你生成一个Vagrantfile
文件,里面有初始化的一些配置
接着我们启动这个Base Box:
vagrant up
Vagrant会首先去搜索你的Vagrant文件目录以及默认的Box目录,在我系统上是C:\Users\Administrator\.vagrant.d\boxes
,如果找到它需要的Box就可以直接启动,如果找不到那么还要去之前说的box官方网站下载box到默认的Box目录,这里我是先下载下来,所以无需去下载,整个启动过程如下:
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'ubuntu/xenial64'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'ubuntu/xenial64' is up to date...
==> default: Setting the name of the VM: Vagrant_default_1488941499616_2827
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 22 (guest) => 2222 (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:2222
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: Mounting shared folders...
default: /vagrant => D:/Vagrant
如此基本的Ubuntu便启动了,前后整个过程不超过3分钟,是不是比之前系统安装的简便很多呀?
我们使用XSHELL工具通过端口2222便可以登录到Ubuntu上,记得这个时候的登录方式可以是SSH Key的也可以是密码方式的。如果是SSH Key的话,公钥就放在之前新建目录Vagrant下面:以我的为例子就是:D:\Vagrant\.vagrant\machines\default\virtualbox
,如果是密码的方式,那么你就得找到这个Base Box的密码,它就放在默认的Box目录下的Vagrantfile
,以卧的为例子:C:\Users\Administrator\.vagrant.d\boxes\ubuntu-VAGRANTSLASH-xenial64\20170303.1.0\virtualbox
,文件内容是:
# Front load the includes
include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)
load include_vagrantfile if File.exist?(include_vagrantfile)
Vagrant.configure("2") do |config|
config.vm.base_mac = "025E4BB29711"
config.ssh.username = "ubuntu"
config.ssh.password = "6ce44951a49047b3d834784e"
config.vm.provider "virtualbox" do |vb|
vb.customize [ "modifyvm", :id, "--uart1", "0x3F8", "4" ]
vb.customize [ "modifyvm", :id, "--uartmode1", "file", File.join(Dir.pwd, "ubuntu-xenial-16.04-cloudimg-console.log") ]
end
end
那么密码一眼就看出来了。这里有一个坑,在后面我们会说一下。
当然我们肯定不会仅仅满足于这样的一个基础空架子,我们要修改这个box为具有前端特性的个人box。
2.2、box改造
根据官方文档的介绍,我们改写整个VagrantFile
文件如下:
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
config.ssh.username = "root"
config.ssh.password = "111111"
config.ssh.insert_key = true
config.vm.define "frontend" do |frontend|
frontend.vm.box = "ubuntu/xenial64"
config.vm.network "forwarded_port", guest: 3000, host: 3000
config.vm.network "forwarded_port", guest: 3001, host: 3001
config.vm.network "forwarded_port", guest: 9090, host: 9090
config.vm.network "forwarded_port", guest: 9091, host: 9091
config.vm.network "forwarded_port", guest: 9098, host: 9098
config.vm.network "forwarded_port", guest: 9099, host: 9099
frontend.vm.hostname = "front-linguang"
frontend.vm.synced_folder "/ubuntuSync", "/home", create: true
frontend.vm.provision "shell", path: "provision-frontend.sh"
end
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 = "2048"
end
end
好了,解读一下配置文件:
Vagrant.configure("2") do |config|
:全局配置,并且表明该配置文件的版本是2
config.vm.define "frontend" do |frontend|
: 当需要启动多个box的时候你就需要这条配置,我们为了兼容以后多个机器的情况,于是使用MULTI-MACHINE的情形
config.vm.network "forwarded_port", guest: 3000, host: 3000
: 配置主机和虚拟机映射的端口,也就是说当从主机访问3000端口的时候是映射到虚拟机的3000端口。
frontend.vm.hostname
: 配置虚拟机中命令提示符的显示名称
frontend.vm.synced_folder "/ubuntuSync", "/home", create: true
: 配置共享文件夹的目录,前者是主机的目录,后者是虚拟机的目录
frontend.vm.provision "shell", path: "provision-frontend.sh"
: 配置机器起来的时候自动执行的脚本,有点类似于Docker中的Dockerfile
。
config.vm.provider "virtualbox" do |vb|
: Provider的配置,比如设置内存2G,CPU核使用几个之类的。
,每一个config之后都有一个end表示当前区块配置结束。
完成这个配置文件遇到了几个彩蛋:
第一个彩蛋是我之前是将frontend.vm.box = "ubuntu/xenial64"
误写成config.vm.box = "ubuntu/xenial64"
,然后在后面的vagrant 操作上就会报如下错误:
刚开始还以为是Vagrant的bug,然后就手动删除.vagrant\machines
目录下所有文件,貌似又恢复了,但是后来不断地测试不断的出现这个问题,就很郁闷了,然后到官网上看文档,才发现我的这种配置属于MULTI-MACHINE,它有另外一套规则的,所以才改成正确的结果
第二个彩蛋便是配置了用户名和密码:
config.ssh.username = "root"
config.ssh.password = "111111"
config.ssh.insert_key = true
折腾这个搞了好久,配置完这个在vagrant up frontend
的时候会一直请求你的密码:
然后我当时是以为是我配置的那个密码,后来仔细研究了一下,我使用的Base Box,这个box不是有之前提过的那个密码吗?于是乎我这样的配置在起初运行的时候是不可行的,因为用户名都是不对的,至于网上说的什么默认密码vagrant
都是没啥卵用,所以有的时候自己分析会比网上靠谱些。
于是解决办法便是先注释掉那些关于SSH的配置,首先进入Base Box,然后修改一些配置,尤其是配置Root密码或者你别的用户的密码,接着再配置允许SSH以root用户登录(可以参考Vmware安装Ubuntu15.10),然后再退出,取消注释,密码修改为你之前给root用户设置的密码,再启动:
Bringing machine 'frontend' up with 'virtualbox' provider...
==> frontend: Importing base box 'ubuntu/xenial64'...
==> frontend: Matching MAC address for NAT networking...
==> frontend: Checking if box 'ubuntu/xenial64' is up to date...
==> frontend: Setting the name of the VM: Vagrant_frontend_1488958836384_70420
==> frontend: Clearing any previously set network interfaces...
==> frontend: Preparing network interfaces based on configuration...
frontend: Adapter 1: nat
==> frontend: Forwarding ports...
frontend: 22 (guest) => 2222 (host) (adapter 1)
==> frontend: Running 'pre-boot' VM customizations...
==> frontend: Booting VM...
==> frontend: Waiting for machine to boot. This may take a few minutes...
frontend: SSH address: 127.0.0.1:2222
frontend: SSH username: ubuntu
frontend: SSH auth method: password
frontend: Warning: Remote connection disconnect. Retrying...
frontend:
frontend: Inserting generated public key within guest...
frontend: Removing insecure key from the guest if it's present...
frontend: Key inserted! Disconnecting and reconnecting using new SSH key...
==> frontend: Machine booted and ready!
==> frontend: Checking for guest additions in VM...
==> frontend: Setting hostname...
==> frontend: Mounting shared folders...
frontend: /home => D:/ubuntuSync
frontend: /vagrant => D:/Vagrant
==> frontend: Running provisioner: shell...
frontend: Running: C:/Users/ADMINI~1/AppData/Local/Temp/vagrant-shell20170308-3944-1540g23.sh
==> frontend: Start provisioning!
2.3、打造属于你自己的Provision
在第一次启动的时候,Vagrant都是会去帮你执行你provision中的配置,为了打造一款基本的前端开发环境,我们的执行脚本会去安装一些基本的包:
#!/bin/bash
echo "Start provisioning!"
echo "add some private repo(nodejs/mongoDB/ruby) to ubuntu"
sudo apt-add-repository ppa:chris-lea/node.js
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
sudo echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
echo "Ubuntu apt-get update"
sudo apt-get update
echo "Ubuntu install basic packages"
sudo apt-get install python-software-properties python g++ make software-properties-common
echo "Installing git"
sudo apt-get install -y git
echo "Installing ruby"
sudo apt-get install -y ruby-full
echo "Installing Sass"
gem install sass
echo "Installing Nginx"
sudo apt-get install -y nginx
echo "Installing MongoDB"
sudo apt-get install -y mongodb-org
echo "Installing Nodejs"
sudo apt-get install -y nodejs
echo "Installing npm"
sudo apt-get install -y npm
sudo chown -R $USER:$GROUP ~/.npm
sudo ln -s /usr/bin/nodejs /usr/bin/node
echo "Installing NRM (globally)"
sudo npm install -g nrm
echo "Swith the npm repository to taobao mirror"
sudo nrm use cnpm
echo "Installing Gulp (globally)"
sudo npm install -g gulp
echo "Installing SailsJs (globally)"
sudo npm install -g sails
echo "Upgrade nodejs to newest stable version"
sudo npm install -g n
sudo n stable
echo "Setting up gitconfig and bash_profile files"
git clone https://github.com/linxiaowu66/PersonalConfigurationFiles.git
cp PersonalConfigurationFiles/.bash_profile .bash_profile
cp PersonalConfigurationFiles/.gitconfig .gitconfig
source .bash_profile
# rm -R dotfiles/
echo "Cleaning the packages"
sudo apt-get clean
sudo rm -rf /var/lib/apt/lists/*
echo "It's all done sweetheart, enjoy! ^.^"
exit
然后大功告成,这样安装下来整个box的尺寸大约是676MB,而Base Box是300MB左右,整体大小仍然是比直接安装Ubuntu少了好几倍的。
2.4、Vagrant常用命令
vagrant halt frontend
: 关掉frontendvagrant suspend frontend
: 休眠frontendvagrant reload frontend [--provision]
: 重启frontend(并强制provisioners 执行provision脚本)vagrant resume frontend
: 唤醒frontendvagrant destroy frontend
: 删除frontend
更多配置参考Vagrant官方文档
3、打包发布你的Vagrant
打造完你的Vagrant后想让更多人都可以使用,这个时候你就需要用下面的命令去打包这个box:
vagrant package --output ubuntu16_frontend.box --vagrantfile Vagrantfile
然后你这个文件就可以放在一些共享的网站上,比如我的这个box可以在这个网站上下载到:
https://pan.baidu.com/s/1bDPNeY
提取密码: xr47
这下子可以享受Vagrant带来的开发乐趣了。。。
参考
公众号关注一波~
网站源码:linxiaowu66 · 豆米的博客
Follow:linxiaowu66 · Github
关于评论和留言
如果对本文 Vagrant-打造一份通用的前端开发环境 的内容有疑问,请在下面的评论系统中留言,谢谢。