Skip to content

Instantly share code, notes, and snippets.

Created April 5, 2019 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save opencoca/fd3e763742f173dcfef847ea6245f5d3 to your computer and use it in GitHub Desktop.
Save opencoca/fd3e763742f173dcfef847ea6245f5d3 to your computer and use it in GitHub Desktop.

Have you worked on team projects only to run into dreaded, "it works for me" problems. Dev teams are supposed to make it easier to work on big projects. Instead, larger teams often mean hours more system setup and sync. Vagrant is here to help build and manage virtual machines. Using it properly makes "works on my machine" issues a thing of the past. With its easy-to-use workflow and focus on automation, Vagrant reduces environment setup time and keeps all your systems in check.

So why bother using Vagrant? Vagrant gives you reproducible, easy to configure, and portable work environments. These environments are built on industry-standard technology and managed through a single constant workflow.

Vagrant stands on the shoulders of giants. Vagrant allows provisioned machines to run on VirtualBox, VMware, AWS, and many other providers. Using, industry-standard tools such as shell scripts, Docker, or Puppet, you can automatically install and configure software on Vagrant virtual machines.

For Developers Vagrant can separate dependencies and configurations inside disposable, consistent environments. You don't have to sacrifice your tools (editors, browsers, debuggers, etc.). With a single Vagrantfile, you only need to use is vagrant up, and everything is installed and configured. Things work best when all the members of your team build dev environment around the same configuration. So whether you are working on Linux, Mac OS X, or Windows, all of your team will run code in the same environment, against the same dependencies, all configured the same way.

For DevOps engineers, Vagrant gives disposable environments and consistent workflows. You are free to quickly check things like shell scripts, Docker Images, Puppet modules, etc. using local virtualization such as VirtualBox. Without needing to change your configuration, you can test these scripts it the cloud with providers like Digital Ocean and AWS. All within the same workflow.

With Vagrant you can abandon many of your custom scripts, stop shuffling SSH prompts to various machines, and bring harmony to your life.

As a designer, Vagrant will automatically set up everything needed for your web-apps. Vagrant lets you focus on doing what you do: design. When a developer configures Vagrant, you don't need to worry about how to get that app running ever again — no more bothering other people with setting things up to test your design concepts. Just check out the project, vagrant up, and start designing.

Vagrant is for everyone — the easiest and fastest way to create a virtualized environment!

Vagrant vs. Other Tools

There are many other tools for virtual machine managment. Let us compare Vagrant to other software choices.

Vagrant vs. CLI Tools

Most virtualization software such as VirtualBox or VMware come with command line utilities for managing virtual machines. Vagrant builds on top of these CLI tools while providing consistent workflow.

Vagrant supports multiple synced folder types, multiple provisioners to set up machines, automat SSH setup, create Network tunnels into your development environment, and more. All of these can be configured using a single simple configuration file.

Even disregarding its higher-level features Vagrant has many other advances over old-fashioned scripting. The many command-line utilities provided by virtualization software often change each version. Vagrant automatically detects these versions, uses the correct flags, and can work around any known issues. You won't run into problems when you're using one version of VirtualBox, and a co-worker is using a different version; instead Vagrant will work consistently.

Vagrant vs. Docker

Where Vagrant deals with managing whole virtual machines, Docker centers its focus on smaller instances. Vagrant is a tool focused on providing a consistent development environment workflow across multiple operating systems. Docker builds on container management that can consistently run software as long as a containerization system exists.

Containers are generally more lightweight than virtual machines, so starting and stopping containers is extremely fast. Docker uses the native containerization functionality on macOS, Linux, and Windows.

Currently, Docker lacks support for specific operating systems such as BSD. If your target deployment is one of these operating systems, Docker will not provide the same production parity as a tool like Vagrant. Vagrant will allow you to run a Windows development environment on Mac or Linux, and vice-versa.

For microservice centred environments, Docker can be attractive because you can quickly start a single Docker Host VM and then start many containers inside the VM very quickly. Vagrant can manage Docker instances like this as well with the Docker provider. The primary benefit of Vagrant is a consistent workflow, but there are many cases where a pure-Docker workflow does make sense.

Both Vagrant and Docker benifit from a huge library of community-contributed "images" or "boxes" simplifying deployment but possibly introducing security issues.

We're going to get started using Vagrant with VirtualBox since it is free, available on every primary system, and built-in to Vagrant. Vagrant does work with many other providers but for now we'll focus on VirtualBox.

Before diving into our first project, please install the latest versions of Vagrant and VirtualBox.

If you can't stick around for all this or are more into books check ourt:Vagrant: Up and Running, the author of Vagrant writes it and published by O'Reilly.

Our first commands:

$ vagrant init ubuntu/xenial64 $ vagrant up This will download the xenial64 box and you will have a virtual machine in VirtualBox running 64 bit Ubuntu 16.04 LTS. Once everything is running SSH in with vagrant ssh, and when you are done looking at the vm, you can terminate the virtual machine with vagrant destroy.

Now imagine if every project you've ever worked on was this simple to set up! With a proper Vagrant file in a project, vagrant up the only commend you need to work. You can install every dependency, and set up any networking and synced folders, so you can continue working from the comfort of your "Personal Computer".

Moving forward we'll walk you through setting up a complete project, covering more features of Vagrant.

You've just created your first virtual environment with Vagrant. Let's move on to learn more about project setup.

Project Setup:

The first step in any Vagrant project is creating a Vagrantfile using vagrant init. The purpose of the Vagrantfile is twofold:

It marks the root directory of our projects. Most of Vagrant's configuration options are relative to this root directory.

It describes the kind of machine and resources vagrant needs to run our project, as well as what software we want it install and how we want to access it.

As we saw Vagrant's built-in command for initializing a directory for usage with Vagrant: vagrant init.

$ cd ~/Desktop $ mkdir vagrant_project $ cd vagrant_getting_started $ vagrant init ubuntu/xenial64 Thes commands create an ubuntu xenial64 Vagrantfile in your current directory. Take a peek at the Vagrantfile. It's packed with commented example settings.

If you have existing projects that you want to use vagrant with feel free to vagrant init in their root directory to set up Vagrant for a current project. I won't easily be able to debug issues you might have.

Your Vagrantfile should be committed to version control with the rest of your project. This way, every person working with that project can benefit from Vagrant without any upfront work.


Instead of continually building virtual machines from scratch, which is slow and tedious, Vagrant uses base images to clone a virtual machine quickly. These base images are known as "boxes" in Vagrant, and specifying the box to use for your Vagrant environment is always the first step after creating a new Vagrantfile.

» Installing a Box If you ran the commands on the getting started overview page, then you've already installed a box before, and you do not need to run the commands below again.

Boxes are added to Vagrant with vagrant box add. "vagrant box add" stores each box under precise names so that multiple Vagrant environments can re-use them. If you have not added a box yet, you can do so now:

$ vagrant box add hashicorp/precise64

This command will download the box named "hashicorp/precise64" from HashiCorp's Vagrant Cloud box catalogue, where you can find and host boxes. While it is easiest to download boxes from HashiCorp's Vagrant Cloud, you can also add boxes from a local file or even custom URLs.

To simplify reuse, Vagrant stores boxes globally. Each project uses a box as an initial image to clone from, and never modifies the actual base image. If you're working on two projects both using the hashicorp/precise64 box, adding files in one guest machine doesn't effect on the other device.

In the above command, you will notice that boxes are namespaced. Boxes are broken down into two parts - the username and the box name - separated by a slash. In the example above, the username is "hashicorp," and the box is "precise64". You can also specify boxes via URLs or local file paths, but we won't cover that today.

Namespaces do not guarantee canonical boxes! A common misconception is that a namespace like "ubuntu" represents the canonical space for Ubuntu boxes. Namespaces on Vagrant Cloud behave very similarly to namespaces on GitHub, for example. Just as GitHub's support team is unable to assist with issues in someone's repository, HashiCorp's support team is unable to help with third-party published boxes.

» Using a Box Now that you have added a box to Vagrant, we need to configure our project to use it as a base. Open the Vagrantfile and change the contents to the following:

Vagrant.configure("2") do |config| = "hashicorp/precise64" end

The "hashicorp/precise64" in this case must match the name you used to add the box above. The exact name is how Vagrant knows what Box to use. When you're missing a box, Vagrant will automatically download and add the box when it at first run.

You may specify an explicit version of a box by specifying config.vm.box_version for example:

Vagrant.configure("2") do |config| = "hashicorp/precise64" config.vm.box_version = "1.1.0" end This is similar to Docker's image:verson syntax.

Next, we will bring up the Vagrant environment and interact with it a little bit.

» Finding More Boxes

Today we will only use the "ubuntu/xenial64" box we added previously. After finishing things here, one of the first questions you will probably have is "where do I find more boxes?"

Currently, the best place to find more boxes is HashiCorp's Vagrant Cloud box catalogue. HashiCorp's Vagrant Cloud has a directory of Vagrant Boxes that run various platforms. HashiCorp's Vagrant Cloud also has great search to allow you to find the box you need.

HashiCorp's Vagrant Cloud lets us host our own open source Boxes, as well as private boxes if you need a little privacy when creating boxes for your team.

» Next Steps So you've successfully downloaded your first Vagrant box and configured the Vagrantfile to utilize it.

Up And SSH If you didn't already lets boot into our Vagrant environment. Run the following from your terminal:

$ vagrant up

In less than a minute, this command will finish, and you will have a virtual machine running Ubuntu. You will not see anything though since Vagrant runs the virtual machine without a UI. To prove that it is running, you can SSH into the computer:

$ vagrant ssh This command will drops us into a full-fledged SSH session. Feel free and go ahead, interact with the machine, do whatever you want. Although it can be tempting ;P , be careful about rm -rf /, since Vagrant shares the folder at /vagrant with the folder on the host containing your Vagrantfile, and this can delete all those files. We'll cover shared folders in more detail shortly.

Let us take a moment to think what just happened: With only two commands in our terminal, Vagrant brought up a fully functional, SSH accessible virtual machine.

vagrant@precise64:~$ logout Connection to closed. When done looking at the machine, run "vagrant destroy" on our host machine and Vagrant terminates the use of any resources by the virtual machine.

The "vagrant destroy" command does not remove the downloaded box file. To completely delete the box file, you use the "vagrant box remove" command.

» Learning Vagrant's Next Steps You have successfully created and interacted with your first Vagrant environment! Now let's learn more about synced folders.

Vagrant Synced Folders It is cool to have a virtual machine so easily! Unfortunately, not many people want to edit files using just plain terminal-based editors over SSH. With Vagrant, you do not have to. Using Vagrant's synced folders files is automatically synchronized between your host and Virtual Machine.

By default, Vagrant shares your project directory to the /vagrant directory in your guest machine.

Note: that when you vagrant ssh into our machine, you're in /home/vagrant. The /home/vagrant is a different directory from the synced /vagrant directory.

Lets run vagrant up again and SSH into our machine to see:

$ vagrant up does it's stuff $ vagrant ssh

vagrant@xenial64:~$ ls /vagrant Vagrantfile

That Vagrantfile you see inside the virtual machine is the same Vagrantfile that is on your actual host machine. Go ahead and touch a file to prove it to yourself:

vagrant@precise64:$ touch /vagrant/test_file vagrant@precise64:$ exit $ ls test_file Vagrantfile "a_file" is instantly on your host machine. Vagrant kept the folders in sync. As you have synced folders, you can continue to use your favourite editor on your host machine and have the files sync into the guest machine.

» Next Steps You have successfully interacted with your host machine via synced folders on the guest machine. Read on to learn about installing packages, users, and more with provisioning.

Provisioning Alright, so we have a virtual machine running a simple copy of Ubuntu, and we can edit files from our computer and have them synced into the virtual machine. Let us now serve those files using a web server.

We could SSH in and install a web server and be on our way, but then every person who used Vagrant would have to do the same thing. Instead, Vagrant has built-in support for automated provisioning. With automatic file provisioning, Vagrant will automatically install software while you vagrant up so that can create the same the virtual machine again and again. Every time it will be ready-to-use.

» Vagrant automatically Installing Apache Let's set up Apache for our basic project, and we will do so using a shell script. Create the following shell script and save it as in the same directory as your Vagrantfile:

#usr/bin/env bash

apt-get update apt-get install -y apache2 if ! [ -L /var/www ]; then rm -rf /var/www ln -fs /vagrant /var/www fi Next, we configure Vagrant to run this shell script when setting up our machine. We do this by editing the Vagrantfile, which should now look like this:

Vagrant.configure("2") do |config| = "hashicorp/precise64" config.vm.provision :shell, path: "" end Now, the "provision" line is new and tells Vagrant to have you shell provisioner set up the machine, using file. Your file's path is relative to the location of the project root (where the Vagrantfile is).

» Provision! Once we configured everything, we just run vagrant up to create your machine and Vagrant automatically provisions it. Watch as the output from the shell script appears in your terminal. When the guest machine is already running, we'll need to run vagrant reload --provision, which will quickly restart your virtual computer. The provision flag instructs Vagrant to run the provisioners, without this flag Vagrant will only do this on the first vagrant up.

Once Vagrant completes working, our web server will be up and running. You cannot see the website from your browser (yet), but you can verify that the provisioning works by loading a file from SSH within the machine:

$ vagrant ssh ... vagrant@precise64:~$ wget -qO-

With this shell script, we installed Apache and set up our default DocumentRoot of Apache to point to our /vagrant directory, which is the default synced folder setup by Vagrant.

You can play around some more by creating some more files and viewing them from the terminal, but in the next step, we will cover networking options so that you can use your browser to access the guest machine.

For complex provisioning scripts, it may be more efficient to package a custom Vagrant box with those packages pre-installed instead of building them each time.

» Up Next Networking You have successfully provisioned your first virtual machine with Vagrant. Read on to learn about networking.

Networking So, we have a web server up and running with the ability to modify files from our host and have them automatically synced to the guest. However, accessing the web pages only from our local terminal is not very satisfying. Let's take advantage of Vagrant's networking features to give us additional options for connecting to our virtual machine from our host system.

» Vagrant Port Forwarding A possibility is to do port forwarding. Port forwarding lets you assign ports on the guest machine to share via a port on the host machine. Allowing you to access a port on your computer, but really, having our network traffic forwarded to a specific port on the guest machine.

Let us set up a forwarded port so we can access Apache. First edit the Vagrantfile, which now looks like this:

Vagrant.configure("2") do |config| = "hashicorp/precise64" config.vm.provision :shell, path: "" :forwarded_port, guest: 80, host: 4567 end Run a vagrant reload or vagrant up (depending on if the machine is already running) so that these changes can take effect.

Once the machine is running again, load in your browser. You should see a web page served from the virtual machine that was automatically setup by Vagrant.

» Other Networking Vagrant also has other forms of networking, allowing you to assign a static IP address to the guest machine, or to bridge the guest machine onto an existing network. If you are interested in other options, read the networking page.

» Next up Sharing Access You have successfully configured networking for your virtual machine using Vagrant. Read on to learn about setting up shares with Vagrant.

Vagrant Sharing Now that we have a web server up and running and accessible from your machine, we have a reasonably functional development environment. In addition to giving us easy to administer development environments, Vagrant also makes it simple to share and collaborate on these environments through Vagrant Share.

Vagrant Share lets you share your Vagrant environment to anyone around the world with an Internet connection. It will give you a URL that will route directly to your Vagrant environment from any device in the world connected to the Internet.

Run vagrant share:

$ vagrant share ... ==> default: Creating Vagrant Share session... ==> default: HTTP URL: ... Your URL will be different, so do not try the URL above. Copy the URL that vagrant share outputted for you and visit that in a web browser. It should load the Apache server we set up.

If you change the files in your shared folder and refresh the URL, you will see it update! The URL is routing directly into your Vagrant environment and should work from any device in the world that connected to the internet.

To end the sharing session, hit Ctrl+C in your terminal. You can refresh the URL again to verify that you are no longer sharing your environment.

Vagrant Share can do much than merely sharing web access. If you come to the WorkShop we'have in a ~ a month we'll go over this more in depth.

I have to note that Vagrant Share is not designed to serve production traffic! Please do not rely on Vagrant share outside of development or Q/A. The Vagrant Share service is not intended to carry production-level traffic.

» Next Steps You have successfully shared your environment with the world. Congratulations! Read on to learn about the teardown process.

Teardown We now have a fully functional virtual machine we can use for web development. But now let us say it is time to switch gears, maybe work on another project, maybe go out to lunch, or perhaps just time to go home. How do we clean up our development environment?

With Vagrant, you suspend, halt, or destroy the guest machine. Each of these options has pros and cons. Choose the method that works best for you.

Suspending the virtual machine by calling vagrant suspend will save the current working state of the system and stop it. When you are ready to begin working again, just run vagrant up, and it will resume everything from where you left off. It's incredible how fast Vagrant can do this! It usually takes only 5 to 10 seconds to stop and start your work. The downside is that the virtual machine still eats up your disk space, and requires even more disk space to store all the state of the virtual machine RAM on disk.

Halting the virtual machine by calling vagrant halt will gracefully shut down the guest operating system and power down the guest machine. You can use vagrant up when you are ready to boot it again. Vagrant will cleanly shut down your virtual machine, preserving the contents of the disk, and allowing it to start it again cleanly. The downside is that it'll take some extra time to start from a cold boot, and the guest machine still consumes disk space.

Destroying the virtual machine by calling vagrant destroy will remove all traces of the guest machine from your system. It'll stop the guest machine, power it down, and remove all of the guest hard disks. When you are ready to work again, issue a vagrant up. The benefit of this is that Vagrant leaves nothing on your machine with this command. You'll reclaim all the disk space and RAM consumed by your guest machine, and your host machine is left clean. As a downside when you need to "vagrant up" to get working things again will take extra time since it has to reimport the machine and re-provision it.

» Next Steps You have successfully suspended, halted, and destroyed your virtual environment with Vagrant. Read on to learn how to rebuild the environment.

Rebuild When you are ready to come back to your project, whether it is tomorrow, a week from now, or a year from now, getting it up and running is easy:

$ vagrant up That's it! Since the Vagrant environment is already all configured via the Vagrantfile, you or any of your coworkers have to run vagrant up at any time and Vagrant will recreate your work environment.

» Next Steps You have successfully managed the full lifecycle of your Vagrant environment. Read on to learn about providers.

Next Steps That's it! You have completed the getting started guide for Vagrant. Here are some interesting topics you might find relevant:

Configuring VirtualBox settings Working with Plugins Customizing Synced Folders Provisioning with Puppet, Docker, or Ansible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment