December 15, 2016
Vagrant is a tool to create and configure VMs for development. You basically write a config file that can be shared with the rest of the team and added to your project repository.
It works with different providers such as VirtualBox or VMWare. This post is an introduction to the configuration and will show you how to quickly setup an Ubuntu box for RVM+Ruby development and another for Apache+PHP.
First you need to install Vagrant and whatever Virtualization software you prefer; I choose VirtualBox but it doesn't make much of a difference.
Both packages are very easy to install, no matter if you are a Linux, Mac or Windows user; they have click-next-to-install packages for you.
Just follow the installation guide for your platform and then open a terminal to make sure you have the 'vagrant' command.
There are many commands you can use but we are going to focus on "vagrant up", "vagrant halt" and "vagrant ssh".
The first one will bring up the development/virtual machine based on what we will put in the configuration file; the second will shut it down, and the third one will allow us to login onto our virtual machine.
As a side note make sure you add "/.vagrant/" to your project .gitignore
The concept of boxes is important to understand; these reefer to virtual machine "images"; or S.O. (but not only limits to that), these are used to create the virtual environment with some tweaks.
In the examples I will be using "ubuntu/xenial64"; for this we only need to type the name on the config file and vagrant will automatically download the necessary files upon creation; what you pick depends on the environment you want to recreate and work with.
View a complete list of available boxes
Usually you are going to run "vagrant up" on your project root path; also here is where we are going to save our required configuration file which by default is named "Vagrantfile" (without any extension).
We write the Config using Ruby syntax, but do not worry if you don't know the language; the config is very simple and pretty straight forward. Bellow is a basic one, the details about each sections are explained in the comments within the code.
Provisioning is the way you customize your box, this can be done by providing a set of SHELL commands, these are executed when the VM is created.
There are two ways of doing this: INLINE and in FILES, where we can just include the commands in a specific section of the Vagrantfile or we can also specify an external Bash file path to load. The last one is very useful if your config file starts to grow.
Also, provisioning is a very large topic and depends a lot of what you are doing; what S.O. you are using and much more. On this introduction post I'll focus on Linux boxes and SHELL provisioning.
# Configuration file version
Vagrant.configure(2) do |config|
# Box name, for a complete list visit:
# http://atlas.hashicorp.com/boxes/search
config.vm.box = "ubuntu/xenial64"
# This isnt required, but for some projects I needed to bump the memory of my
# the virtual machine thats going to be created.
config.vm.provider "virtualbox" do |v|
v.memory = 1024
end
# Simple rooting config. This allows you for example to type
# http://localhost:8888 in your browser and get whatever
# service is running in your virtual machine's 80
config.vm.network "forwarded_port", guest: 80, host: 8888
# (Carefull here). This line allows the VM to work just like any other
# computer in you network; maybe usefull when you want to share or just
# connect 2 VMs.
#config.vm.network "private_network", ip: "192.168.33.10"
# This one is specific for Virtualbox, allows your to have
# network/internet access in the virtualmachine. Maybe you are writing
# an app that needs to connect to some external API service like
# Twitter API
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
v.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
end
# Provisioning method (1): Inline
config.vm.provision "shell", inline: <<-SHELL
apt-get -y update
# Add more commands here....
SHELL
# Provisioning method (2): You must create a file
# named provisionfile.sh next to your Vagrantfile
#config.vm.provision "shell", path: "provisionfile.sh"
end
So, you just created the config file(s) next step is to run "vagrant up". If this is the first time it may take some time, it may download stuff... so be patient, you'll get a many console messages but as long none of them are errors you are good to go.
Next is "vagrant ssh"; this logs you in into your the new virtual machine command prompt. But what about your projects files, and how are these shared with the virtual environment?
By default, the folder where you created the Vagrantfile (on YOUR computer) is the folder that is shared with the VM, so if you have something like this:
daniel-air:test daniel$ ls
.gitignore index.php Vagrantfile vendor
Then on the VM the files are shared in the /vagrant folder. Following the previous example you get something like this:
daniel-air:test daniel$ vagrant ssh
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 3.13.0-91-generic x86_64)
vagrant@vagrant-ubuntu-trusty-64:~$ cd /vagrant
vagrant@vagrant-ubuntu-trusty-64:~$ ls
.gitignore index.php Vagrantfile vendor
And yes!, there are many options to change the mount point, adding multiple folders, etc.
Simple provision to include in the project to setup a Ruby dev environment.
#!/bin/bash
RUBY_VERSION="2.2.2"
apt-get update
apt-get -y install git nodejs curl git curl unzip
# Install rvm
if ! type rvm >/dev/null 2>&1; then
curl -sSL https://rvm.io/mpapis.asc | gpg --import -
curl -L https://get.rvm.io | bash -s stable
source /etc/profile.d/rvm.sh
# Add vagrant's users to rvm group
usermod -a -G rvm vagrant
usermod -a -G rvm ubuntu
fi
# Install ruby
if ! rvm list rubies ruby | grep ruby-${RUBY_VERSION}; then
rvm install ${RUBY_VERSION}
fi
# Set our Ruby version
rvm --default use ${RUBY_VERSION}
# Install our default global gems
gem install bundler
# Remove unnecessary stuff
apt-get -y autoremove
#
# Add more here ... !
#
This is also a very simple setup, it assumes you have a {projectpath}/public directory in YOUR PC (next to your Vagrantfile).
This one is a bit longer but the "trick" here is that it creates a new Apache "virtual host" and then we set the DocumentRoot to /vagrant/public. It also installs composer.
Download base project here. (also includes MySQL and phpMyAdmin)
#!/bin/bash
# Some vars
apache_config_file="/etc/apache2/envvars"
apache_vhost_file="/etc/apache2/sites-available/vagrant_vhost.conf"
# This is the public folder of your project, where something like index.php is.
project_web_root="/vagrant/app/public"
apt-get update
# Some utilities i like to have
apt-get -y install git curl unzip
# Installing Apache
apt-get -y install apache2
# Create our new virtual host
if [ ! -f "${apache_vhost_file}" ]; then
cat << EOF > ${apache_vhost_file}
ServerAdmin webmaster@localhost
DocumentRoot ${project_web_root}
LogLevel debug
ErrorLog /var/log/apache2/error.log
CustomLog /var/log/apache2/access.log combined
AllowOverride All
Require all granted
EOF
# Disable default "hello world" site, and enable ours
a2dissite 000-default
a2ensite vagrant_vhost
# PHP 7; also Curl and Cli are required by composer
apt-get -y install php php-curl php-cli libapache2-mod-php
# Some other packages
apt-get -y install php-mcrypt php-mbstring php-intl
# Install latest version of Composer globally
if [ ! -f "/usr/local/bin/composer" ]; then
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
fi
# restart apache
service apache2 restart
# Remove unnecessary stuff
apt-get -y autoremove
I'm a 32-years old programmer and web developer currently living in Montevideo, Uruguay. I been programming since I was about 15 y.o, and for the past 12 actively working in the area.