Getting Started with Vagrant — The Complete Guide

Utsav Desai
11 min readFeb 5, 2023

--

What is Vagrant?

Vagrant is an open-source tool for building and managing virtual development environments. It allows developers to create a single configuration file that specifies the software components and settings for a virtual machine, which can then be easily reproduced on any host machine.

Vagrant helps to simplify and streamline the process of setting up and maintaining virtual environments, making it easier for developers to work in a consistent, reproducible environment. Vagrant integrates with popular configuration management tools, making it a valuable tool in DevOps for managing development, testing, and production environments.

Why Vagrant?

There are several reasons to learn Vagrant:

  1. Consistent Development Environments: By using Vagrant, developers can ensure that their development environment is consistent and reproducible across multiple machines. This helps to reduce the “works on my machine” problem, ensuring that code works consistently across different environments.
  2. Testing: Vagrant can be used to set up test environments quickly and easily, allowing developers to test their code in a variety of different configurations. This helps to ensure that code is thoroughly tested before it is deployed to production.
  3. Infrastructure as Code: Vagrant allows the creation of virtual machines to be automated and managed as code. This enables the entire infrastructure to be version controlled, making it easier to track changes and collaborate with other team members.
  4. Deployment: Vagrant can be integrated with configuration management tools such as Ansible and Puppet, making it possible to automatically provision and configure virtual machines as part of the deployment process.
  5. Ease of Use: Vagrant is designed to be easy to use, with a simple and intuitive command-line interface. It is also highly customizable, allowing developers to configure their virtual environments to meet their specific needs.

Overall, learning Vagrant is a valuable investment for developers, as it provides a simple and efficient way to manage virtual environments for development, testing, and production.

Vagrant to set up any virtual machine:

Complete instructions are provided for setting up our virtual computer.

1. Install Vagrant on your host machine.

Run the following command to install Vagrant:

$ vagrant.msi

2. Create a new directory for your project and navigate to it in the command line.

$ mkdir vagrant_project
$ cd ~/vagrant_project

3. Visit the website and choose your VagrantBox (built-in virtual environment image of an operating system).

$ vagrant init ubuntu/trusty64

4. Modify the generated Vagrantfile to specify the virtual machine configuration you want.

For example, you can change the virtual machine ubuntu/trusty64 to ubuntu/focal64.

config.vm.box = "ubuntu/focal64"

5. Start the virtual machine by running the command.

$ vagrant up

6. Connect to the virtual machine using the command.

$ vagrant ssh

7. When you’re finished, exit the virtual machine and shut it down by running the command.

$ vagrant halt

8. To destroy the current Vagrant environment, run the following command.

$ vagrant destroy

9. To reload the Vagrant environment, run the following command.

$ vagrant reload

10. To verify that the environment has been reloaded successfully, you can run the following command.

$ vagrant status

This is just a simple example of how to use Vagrant to set up a virtual machine. You can further customize the virtual environment by specifying additional configuration options in the Vagrantfile, such as network settings, synced folders, and provisioning scripts. With Vagrant, you can create complex virtual environments with ease, making it an essential tool for DevOps and development.

Vagrant additional configuration options in the Vagrantfile to further customize the virtual environment.

Here are some examples of the most common configurations:

  • Network Settings: You can specify network settings for the virtual machine, such as a static IP address or a bridged network connection.
config.vm.network "private_network", ip: "192.168.33.10"
  • Synced Folders: You can specify folders that should be synced between the host machine and the virtual machine. This makes it easier to access files in both environments.
config.vm.synced_folder "src/", "/var/www"
  • Provisioning Scripts: You can specify provisioning scripts that will automatically install software and configure the virtual machine when it is first created. For example, you can use a shell script to install Apache and PHP:
config.vm.provision "shell", inline: <<-SHELL
sudo apt-get update
sudo apt-get install apache2
sudo apt-get install php
SHELL
  • Port Forwarding: You can forward ports from the host machine to the virtual machine, allowing you to access the virtual machine’s services from your host machine.
config.vm.network "forwarded_port", guest: 80, host: 8080

These are just a few examples of the many configuration options that are available in Vagrant. By specifying these options in the Vagrantfile, you can easily create complex virtual environments that meet your specific needs. With Vagrant, you can automate the process of setting up and configuring virtual machines, making it a valuable tool in DevOps and development.

Website Setup with Vagrant: An Automated Approach

1. Install Vagrant on your host machine.

Run the following command to install Vagrant:

$ vagrant.msi

2. Create a new directory for your project and navigate to it in the command line.

$ mkdir website-setup
$ cd ~/website-setup

3. Visit the website and choose your centos7 Vagrant box.

$ vagrant init geerlingguy/centos7

4. Modify the generated Vagrantfile to specify the virtual machine configuration you want.

My GitHub project is installed on the virtual machine, and my website is hosted at my IP address.

# -*- 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
# backward compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented on below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.

# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "geerlingguy/centos7"

# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.15"

# Create a public network, which generally matched to bridged network.
config.vm.network "public_network"

# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"

# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant.
config.vm.provider "virtualbox" do |vb|
vb.memory = "2404"
vb.cpus = "2"
end

# Enable provisioning with a shell script.
config.vm.provision "shell", inline: <<-SHELL
yum install httpd wget unzip -y
systemctl start httpd
systemctl enable httpd
cd /tmp/
wget https://github.com/UtsavDesai987/RandomScript/archive/refs/heads/main.zip
unzip -o main.zip
cd RandomScript-main/
cp -r * /var/www/html/
systemctl restart httpd
SHELL
end

5. Start the virtual machine by running the command.

$ vagrant up

6. Display your hosting site in your IP address.

In our example:

http://192.168.33.15/

7. When you’re finished, exit the virtual machine and shut it down by running the command.

$ vagrant halt

WordPress Setup with Vagrant: An Automated Approach

1. Install Vagrant on your host machine.

Run the following command to install Vagrant:

$ vagrant.msi

2. Create a new directory for your project and navigate to it in the command line.

$ mkdir wordpress-setup
$ cd ~/wordpress-setup

3. Visit the website and choose your ubuntu Vagrant box.

$ vagrant init geerlingguy/ubuntu2004

4. Modify the generated Vagrantfile to specify the virtual machine configuration you want.

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

# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "geerlingguy/ubuntu2004"

# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.12"

# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
config.vm.network "public_network"

# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"

# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for 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
#
# View the documentation for the provider you are using for more
# information on available options.

# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
config.vm.provision "shell", inline: <<-SHELL
sudo apt update
sudo apt update
sudo apt install apache2 \
ghostscript \
libapache2-mod-php \
mysql-server \
php \
php-bcmath \
php-curl \
php-imagick \
php-intl \
php-json \
php-mbstring \
php-mysql \
php-xml \
php-zip -y

sudo mkdir -p /srv/www
sudo chown www-data: /srv/www
curl https://wordpress.org/latest.tar.gz | sudo -u www-data tar zx -C /srv/www

cp /vagrant/wordpress.conf /etc/apache2/sites-available/wordpress.conf
sudo a2ensite wordpress
sudo a2enmod rewrite
sudo a2dissite 000-default
sudo service apache2 reload

mysql -u root -e 'CREATE DATABASE wordpress;'
mysql -u root -e 'CREATE USER wordpress@localhost IDENTIFIED BY "admin123";'
mysql -u root -e 'GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON wordpress.* TO wordpress@localhost IDENTIFIED BY "admin123";'
mysql -u root -e 'FLUSH PRIVILEGES;'

sudo -u www-data cp /srv/www/wordpress/wp-config-sample.php /srv/www/wordpress/wp-config.php
sudo -u www-data sed -i 's/database_name_here/wordpress/' /srv/www/wordpress/wp-config.php
sudo -u www-data sed -i 's/username_here/wordpress/' /srv/www/wordpress/wp-config.php
sudo -u www-data sed -i 's/password_here/admin123/' /srv/www/wordpress/wp-config.php

service mysql restart

SHELL
end

Manually set up wordpress.conf file in the same directory.

<VirtualHost *:80>
DocumentRoot /srv/www/wordpress
<Directory /srv/www/wordpress>
Options FollowSymLinks
AllowOverride Limit Options FileInfo
DirectoryIndex index.php
Require all granted
</Directory>
<Directory /srv/www/wordpress/wp-content>
Options FollowSymLinks
Require all granted
</Directory>
</VirtualHost>

5. Start the virtual machine by running the command.

$ vagrant up

6. Display your hosting site in your IP address.

In our example:

http://192.168.33.12/

7. When you’re finished, exit the virtual machine and shut it down by running the command.

$ vagrant halt

Note: All of this is done manually by following this website.

Efficient Multi-VM Setup with Vagrant

1. Install Vagrant on your host machine.

Run the following command to install Vagrant:

$ vagrant.msi

2. Create a new directory for your project and navigate to it in the command line.

$ mkdir website-setup
$ cd ~/website-setup

3. Create Vagrantfile to specify the multi-virtual machine configuration you want.

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

# for website setup
config.vm.define "web" do |web|
web.vm.box = "geerlingguy/centos7"
web.vm.network "private_network", ip: "192.168.33.15"
web.vm.network "public_network"
web.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
vb.cpus = 2
end
web.vm.provision "shell", inline: <<-SHELL
yum install httpd wget unzip -y
systemctl start httpd
systemctl enable httpd
cd /tmp/
wget https://github.com/UtsavDesai987/RandomScript/archive/refs/heads/main.zip
unzip -o main.zip
cd RandomScript-main/
cp -r * /var/www/html/
systemctl restart httpd
SHELL
end

# for wordpress setup
config.vm.define "db" do |db|
db.vm.box = "geerlingguy/ubuntu2004"
db.vm.network "private_network", ip: "192.168.33.12"
db.vm.network "public_network"
db.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
vb.cpus = 2
end
db.vm.provision "shell", inline: <<-SHELL
sudo apt update
sudo apt update
sudo apt install apache2 \
ghostscript \
libapache2-mod-php \
mysql-server \
php \
php-bcmath \
php-curl \
php-imagick \
php-intl \
php-json \
php-mbstring \
php-mysql \
php-xml \
php-zip -y

sudo mkdir -p /srv/www
sudo chown www-data: /srv/www
curl https://wordpress.org/latest.tar.gz | sudo -u www-data tar zx -C /srv/www

cp /vagrant/wordpress.conf /etc/apache2/sites-available/wordpress.conf
sudo a2ensite wordpress
sudo a2enmod rewrite
sudo a2dissite 000-default
sudo service apache2 reload

mysql -u root -e 'CREATE DATABASE wordpress;'
mysql -u root -e 'CREATE USER wordpress@localhost IDENTIFIED BY "admin123";'
mysql -u root -e 'GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON wordpress.* TO wordpress@localhost IDENTIFIED BY "admin123";'
mysql -u root -e 'FLUSH PRIVILEGES;'

sudo -u www-data cp /srv/www/wordpress/wp-config-sample.php /srv/www/wordpress/wp-config.php
sudo -u www-data sed -i 's/database_name_here/wordpress/' /srv/www/wordpress/wp-config.php
sudo -u www-data sed -i 's/username_here/wordpress/' /srv/www/wordpress/wp-config.php
sudo -u www-data sed -i 's/password_here/admin123/' /srv/www/wordpress/wp-config.php

service mysql restart
SHELL
end
end

Manually set up wordpress.conf for WordPress setup.

<VirtualHost *:80>
DocumentRoot /srv/www/wordpress
<Directory /srv/www/wordpress>
Options FollowSymLinks
AllowOverride Limit Options FileInfo
DirectoryIndex index.php
Require all granted
</Directory>
<Directory /srv/www/wordpress/wp-content>
Options FollowSymLinks
Require all granted
</Directory>
</VirtualHost>

4. Start the virtual machine by running the command.

$ vagrant up

5. Display your hosting site in your IP address.

For Website:

http://192.168.33.15/

For WordPress:

http://192.168.33.12/

6. When you’re finished, exit the virtual machine and shut it down by running the command.

$ vagrant halt

In conclusion, Vagrant is a powerful tool for managing virtual environments in DevOps and development. It enables developers to easily create and configure virtual machines, ensuring consistency across development environments, and making it easier to test and deploy code. With its ability to automate the provisioning process, Vagrant provides an efficient and flexible solution for virtual machine management. By using Vagrant, developers can streamline their workflow and improve their productivity, making it a valuable tool for any software development project.

--

--

Utsav Desai

Utsav Desai is a technology enthusiast with an interest in DevOps, App Development, and Web Development.