Advertisement
Scroll to top
Read Time: 9 min

Overview

Vagrant allows you to easily manage and control multiple virtual machines. It is built on top of VirtualBox and VMWare, and it provides many exciting capabilities. You can create isolated development environments, experiment with new products and technologies, install new versions of existing packages, create your own private data center on your laptop, and run different operating systems. All that is available in an easy-to-manage and totally safe silo that can't interfere with your main activities and operating system. 

In this tutorial, I'll show you how to set up Vagrant and start exploring the wealth of opportunities it affords.

Vagrant recently added support for Docker containers too, but I will not discuss that in this tutorial.

Installation

  1. Download the free VirtualBox for your operating system from the VirtualBox website.
  2. After download, just run the binary and install it.
  3. Download Vagrant.
  4. Again, just run the binary to install it.

Initializing Vagrant

Vagrant is a command-line based tool. Once installation is complete, open a console window and create a new directory called 'vagrant_intro'.

1
cd ~
2
3
mkdir vagrant_intro
4
5
cd vagrant_intro

This will be your working directory from now on. Inside the vagrant_intro directory, type:

vagrant init ubuntu/trusty64

You should see the following text:

1
A 'Vagrantfile' has been placed in this directory. You are now
2
3
ready to 'vagrant up' your first virtual environment! Please read

4


5
the comments in the Vagrantfile as well as documentation on
6
7
'vagrantup.com' for more information on using Vagrant. 

The generated 'Vagrantfile' is a Ruby file that controls your [one or more] virtual machines. It is a pretty big file with lots of commented out options. I will go over the important ones later, but let's give it a try first. Type: vagrant up.

This will cause Vagrant to download a prepared virtual box with the 64-bit Ubuntu 14.04 (trusty) release. It will take a while (several minutes) and spit a lot of text to your screen. While Vagrant is churning, let's talk about what a VM is in practical terms.

One view (which I usually adopt) is that the VM simulates a remote server. You should only communicate with it over its network interface. This is particularly useful for testing distributed systems where you shouldn't take advantage of any special VM-host interfaces because they will not be available on your production systems. When operating in this mode, you will normally communicate with your VM over SSH (possibly with a tool like Ansible).

Another view, which is also totally correct and valid, is to think of the VM as another OS running on your local machine. This view is useful if you want to develop directly on your target OS. 

For example, a very common setup is to have developers write their code on a Mac using Mac OS X, but deploy to a Linux production environment. If you want to make sure that the code you develop on the Mac runs properly on Linux without having to deploy to a remote server, you can take advantage of synced folders where you read and write files on the host OS (typically Mac OS X) and have them immediately available on the guest OS (typically Linux). 

This drops the "deploy" step from the edit-deploy-test cycle when working with remote systems. It also removes the need for an expansive staging environment that is a shared resource and needs to be managed carefully across all developers. With a local VM, nobody is going to break your environment, and you can experiment as much as you want without worrying about breaking someone else's code.

You can, of course, use both synced folders and still SSH into your VM. There are other options that blur the borders such as port mapping.

The Vagrantfile

Here is a stripped-down version of the Vagrantfile with some of the most important options:

1
Vagrant.configure(2) do |config|
2
3
  config.vm.box = "ubuntu/trusty64"
4
5
  config.vm.network "forwarded_port", guest: 80, host: 8080
6
7
  config.vm.network "private_network", ip: "192.168.33.33"
8
9
  config.vm.synced_folder "~/vagrant_intro/data", "/vagrant_data"
10
11
  machine.vm.hostname = "gigi.playground.local"

The syntax is Ruby, which gives you a lot of flexibility if you want to add conditionals and loops. This is particularly helpful if you use your Vagrantfile to manage a cluster of virtual machines.

Connecting to Your VM

You can connect to your running VM by typing: vagrant ssh.

This will launch an SSH session and let you fiddle with your VM interactively.

1
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-74-generic x86_64)
2
3
4
5
 * Documentation:  https://help.ubuntu.com/
6
7
8
9
  System information as of Tue Feb  9 06:17:28 UTC 2016
10
11
12
13
  System load:  0.97              Processes:           80
14
15
  Usage of /:   3.4% of 39.34GB   Users logged in:     0
16
17
  Memory usage: 25%               IP address for eth0: 10.0.2.15
18
19
  Swap usage:   0%
20
21
22
23
  Graph this data and manage this system at:
24
25
    https://landscape.canonical.com/
26
27
28
29
  Get cloud support with Ubuntu Advantage Cloud Guest:
30
31
    https://www.ubuntu.com/business/services/cloud
32
33
34
35
0 packages can be updated.
36
37
0 updates are security updates.
38

Once inside your VM, you can pretty much do anything you want: run commands, create users, create files and directories, etc. You are logged in as the 'vagrant' user, which has sudo privileges, so you have full control over the VM.

Exchanging Data With Your VM

Vagrant automatically maps the folder on the host machine that contains the Vagrantfile to the /vagrant directory inside the guest machine. This lets you edit files in your favorite editor on the host machine and have it available in the guest or alternatively have the guest write some output file to the /vagrant directory and browse the synced folder on the host.

Mapping Guest Ports

Often you'll want to run some application that communicates through a port. The most common one is a web server. Vagrant allows you to forward guest ports to the host machine. 

For example, in the configuration above, the guest port 80 is mapped to the host 8080 port. What that means is that whatever service is running on port 80 in the guest can be accessed as localhost:8080 on the host machine. 

Let's see a demonstration. First, I'll put a simple index.html file in the ~/vagrant_intro directory on the host that is synced with the /vagrant_data directory on the guest.

1
<html>
2
3
<body>
4
5
<h1>Vagrant is awesome!</h1>
6
7
</body>
8
9
</html>

Then, after I SSH into the guest machine, I'll run a little web server in the /vagrant_data dir:

1
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ sudo python3 -m http.server 80
2
3
Serving HTTP on 0.0.0.0 port 80 ...

This one-liner Python HTTP server simply serves any static file in its working directory. Now, since port 80 is mapped to the host's 8080 port, you can browse to localhost:8080 and view the result of running the server.

Connecting to the VM Through the Network

You can also connect to the VM through its IP address as if it's a really separate server. I always add a hostname to /etc/hosts so I don't have to use the naked IP address and because the code I'm testing is usually configured with the hostname of a production system. This is what you need to add to your /etc/hosts file:

1
# Important production system

2
3
192.168.33.33 production.server.com

Now, any network access to "production.server.com" on your machine will be sent to your VM.

In this case, the programs that usually connect to the remote server are configured with the VM IP address or hostname. Prior to Vagrant 1.7, there was a single private key that could be used for all machines. This was a serious security problem when people exposed their virtual machine over public networks and anyone could SSH in and get root access. Starting with version 1.7, Vagrant generates a fresh key pair for each machine. To find out where the private key for your machine is, run this command: vagrant ssh-config.

Here is how you can SSH directly to the VM:

1
ssh -o UserKnownHostsFile=/dev/null -o CheckHostIP=no -o StrictHostKeyChecking=no -i ~/vagrant_intro/.vagrant/machines/default/virtualbox/private_key vagrant@192.168.33.33

Managing Your Virtual Boxes

Vagrant provides many commands to manage boxes. Let's explore. To see a list of commands, type: vagrant.

1
Usage: vagrant [options] <command> [<args>]
2
3
4
5
    -v, --version                    Print the version and exit.
6
7
    -h, --help                       Print this help.
8
9
10
11
Common commands:
12
13
     box             manages boxes: installation, removal, etc.
14
15
     connect         connect to a remotely shared Vagrant environment
16
17
     destroy         stops and deletes all traces of the vagrant machine
18
19
     global-status   outputs status Vagrant environments for this user
20
21
     halt            stops the vagrant machine
22
23
     help            shows the help for a subcommand
24
25
     init            initializes a new Vagrant environment by creating a Vagrantfile
26
27
     login           log in to HashiCorp's Atlas

28


29
     package         packages a running vagrant environment into a box

30


31
     plugin          manages plugins: install, uninstall, update, etc.

32


33
     provision       provisions the vagrant machine

34


35
     push            deploys code in this environment to a configured destination

36


37
     rdp             connects to machine via RDP

38


39
     reload          restarts vagrant machine, loads new Vagrantfile configuration

40


41
     resume          resume a suspended vagrant machine

42


43
     scp             copies data into a box via SCP

44


45
     share           share your Vagrant environment with anyone in the world

46


47
     ssh             connects to machine via SSH

48


49
     ssh-config      outputs OpenSSH valid configuration to connect to the machine

50


51
     status          outputs status of the vagrant machine

52


53
     suspend         suspends the machine

54


55
     up              starts and provisions the vagrant environment

56


57
     version         prints current and latest Vagrant version

58


59


60


61
For help on any individual command run `vagrant COMMAND -h`

62


63


64


65
Additional subcommands are available, but are either more advanced

66


67
or not commonly used. To see all subcommands, run the command

68


69
`vagrant list-commands`.

I covered some of the most common commands earlier. The box commands allow you to manage your boxes directly. For example, to see all the VMs on your machine, type vagrant box list. You can update boxes to the latest version with update. The reload command is very useful if you change your Vagrantfile. Finally, provision lets you provision, configure and install software on your VM using various provisioners including Chef, Puppet, Salt, my favorite Ansible, and even Docker.

Conclusion

Vagrant gives you an easy-to-use computer within computer. You can manage a fleet of VMs for diverse purposes, and the Vagrantfile is your interface for specifying how the VM should behave. Have fun exploring Vagrant. I just scratched the surface here.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.