How to Set Up an Nginx Web Server in Ubuntu Virtual Machine Using Vagrant
Tags: devops, nginx, virtualmachine, docker
Published: 2023-05-05 16:16:55

If you explore many Developers and DevOps toolkits, you'll likely come across Vagrant - a tool that is widely used by teams to develop virtual environments that mirror the production environment. One of the advantages of using Vagrant is its ability to reduce the occurrence of bugs or issues before delivering code to the production environment.

In this project tutorial, you'll gain insight into the process of setting up an Nginx web server on Ubuntu, along with how to manually and automatically replace the Nginx default page with an actual web page using Vagrant. By the end of this tutorial, you'll have learned how to:

- Install Vagrant and VirtualBox on your local machine.
- Set up Ubuntu virtual machine in VirtualBox using Vagrant
- Set up an Nginx web server on Ubuntu to host a web page.
- Replace the default Nginx web server home page with our web application.
- Automatically host our web page on Nginx using Vagrant.
- Validate and access it from your local machine's web browser.

## Vagrant

Vagrant is an open source tool for creating and managing reproducible virtual development environments that run on any machine. It manages virtual machines with a configuration file called Vagrantfile. This file is sharable and controls the lifecycle of a virtual machine, including starting, halting, and provisioning them.  Let's imagine you have a Vagrantfile that was created by someone else on your computer. You can replicate the same environment or virtual machine (VM) as the original with merely the "vagrant up" command. 
In 2010, HashiCorp created Vagrant, which is widely used in the technological stacks of organizations including Airbnb, Accenture, Coursera, and Shopify. Several virtualization service providers, including VirtualBox, VMware, Docker, and Hyper-V, are supported by Vagrant.

## VirtualBox
VirtualBox is a free virtualization software that helps users run a second computer with a different operating system from their host computer. As in our case, we will run an Ubuntu operating system in VirtualBox separate from our Windows host computer. VirtualBox supports a variety of operating systems, including Windows, Linux, and macOS. It also comes with some nice features. For example, it supports virtual networking, which enables communication between virtual machines and the host computer. When testing network configurations or running servers in a virtual environment, this can be incredibly helpful. 


## Ubuntu
Ubuntu is one of the most widely used Linux distributions based on the Linux Kernel. In this tutorial, this will be utilized to run our web server.

## NGINX
Nginx is a popular web server software that is widely used to host both static and dynamic web pages that can be accessed by users over the internet.

## Before You Dive In

- As a prerequisite, your computer needs to have around 10GB of free disk space and at least 8GB of RAM to run Linux in a virtual machine.
-  Follow the instructions provided in the official VirtualBox documentation to [download and install VirtualBox](https://www.virtualbox.org/wiki/Downloads) 
- Similarly, [download and install Vagrant](https://www.vagrantup.com/) by following the instructions provided on the official Vagrant documentation.

## Creating an Ubuntu Virtual Machine Using Vagrant
Assuming you have your VirtualBox and Vagrant installed, we'll begin by setting up a virtual machine using Vagrant. We need to first create a new directory on our desktop. To do this, use your Windows Command Prompt or Windows Powershell to execute the following commands:

```
cd Desktop       
mkdir myproject
cd myproject
vagrant init
```

Your terminal should look like this:

![A terminal showing some commands](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/myupnag544j6fniagrko.png)

At **line 1** you used the `cd` command to navigate into your desktop environment. While in **line 2**, you used the `mkdir` command to create a new folder or directory called `myproject` on your desktop. Next, you `cd` into the newly created directory in **line 3**. Then, you initialize a new vagrant machine in **line 4**.

After executing the command at **line 4**, you’ll notice that a `Vagrantfile` has been created inside your directory.  Let's add some setup to our 'Vagrantfile' before starting our virtual environment.

Launch the Vagrantfile using a code editor. In this tutorial, I'm using Visual Studio Code.
Edit the file by adding the following code:


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

 
### Nginx VM ###
  config.vm.define "web01" do |web01|
    web01.vm.box = "ubuntu/bionic64"
    web01.vm.hostname = "web01"
    web01.vm.network "private_network", ip: "192.168.56.18"
    web01.vm.provider "vmware_desktop" do |vmware|
      vmware.gui = true
      vmware.allowlist_verified = true
    end
  end
 
end  
```


Let me explain what the file does. This Vagrant configuration file specifies a virtual machine with the name "web01" that will run an Ubuntu Bionic 64-bit operating system. Here's what each line does:


```ruby
Vagrant.configure("2") do |config|
``` 
Starts the Vagrant configuration block and specifies that version 2 of the configuration API should be used.

```ruby
config.vm.define "web01" do |web01|
``` 
Creates a new virtual machine named `web01` and defines its settings.

```ruby
web01.vm.box = "ubuntu/bionic64"
```
Sets the base box image to `ubuntu/bionic64`.

```ruby
web01.vm.hostname = "web01"
```
Sets the hostname of the virtual machine to `web01`.

```ruby
web01.vm.network "private_network", ip: "192.168.56.18"
```
Adds a private network interface to the virtual machine with an IP address of `192.168.56.18`.

```ruby
web01.vm.provider "vmware_desktop" do |vmware|
```
Sets the virtualization provider to `vmware_desktop` and defines its settings.

```ruby
vmware.gui = true
```
Enables the GUI mode for the virtual machine.

```ruby
vmware.allowlist_verified = true
```
serves as a setting that VMware box has been properly configured for allow list VMX settings. 

Finally, the `end` tags closes the `Vagrant.configure`, `config.vm.define`, and the `Vagrant.configure` blocks respectively.


_Note: If the IP address "192.168.56.18" is already in use on your computer, you can select an alternative "IP" address._

Launch the virtual machine using:
```
vagrant up
```

This will take a few minutes to boot up the VM. Login to the web01 VM using the command:
```
vagrant ssh web01
```

![terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/00b3tiue5zqhay7kelfk.png)

Your directory should change to `vagrant@web01:~$` if successful just as in the image above.

Verify Hosts entry
```
cat /etc/hosts
```

Update the Ubuntu operating system with the latest patches by running the following commands:

```
sudo apt update
sudo apt upgrade
```

Install Nginx:
```
sudo apt install nginx -y
```

After installing Nginx, let's check that it's up and running with the command:
```
systemctl status nginx
``` 

![terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfx5wxws1nxnpxdv4t7z.png)

The nginx web server is active (running) as seen in the image above.

## Accessing Nginx Web Server on Browser

After setting up our VM and installing Nginx, we can now access our web server in a browser using the private IP address that we previously defined in our Vagrantfile.

To confirm that our virtual machine's network setting is as specified in the Vagrantfile, which is `ip: 192.168.56.18`. Inside the SSH session, run:

```
ip addr
```

![terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7oiift3cebre25pf2ngw.png)

You should have an output similar to the one seen in the image above. The output verifies that the VM’s IP address is set to `192.168.56.18` and we can access the web server in our browser using the IP address.
Open your browser and enter “http:// Your IP ADDRESS”. For instance, `http://192.168.56.18`.

![nginx web page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k1dsfnh626t79xb2mpg0.png)


## Nginx Demo Page

Good job if you've made it this far.The default Nginx page serves as a confirmation that Nginx is installed and running correctly. In the next section, We'll explore the steps in replacing the default Nginx page with our website so that users can see our content right away.

You can change the appearance of the Nginx demo page by modifying the default `index.html` file. To edit the file, run the following commands:
```
cd /var/www/html
ls -al
``` 
This will  cd into the /var/www/html directory and  list all the files in the directory
You’ll see a file called `index.html` or as in my case `index.nginx-debian.html`

Use nano editor to edit the file:
```
sudo nano index.nginx-debian.html
or
sudo nano index.html
``` 

Your output should look like this:

![nginx terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0fcr5gek5h8f4b8zhvkl.png)

You can proceed to edit the page to give it the appearance you desire. As an example, you can either add a background color or an image. Press `ctrl+o` to save the edited file, and `ctrl+x` to close the nano editor. Type `logout` to exit the Ubuntu virtual machine.


## Replace the Default Page with your Website

We will upload an actual website in place of the default Nginx page in this section. The source code for this tutorial can be accessed via a [GitHub link](https://github.com/Roseline-Bassey/Vagrant-Project). I have modified [Dinesh Pandiyan](https://github.com/flexdinesh/dev-landing-page)’s simple html and css open source landing page to make it uniquely mine. You can personalize this as well.

Create a new folder called `samplepage` in the `myproject` directory which we previously created. Make sure you’re in the root directory before executing this command:
```
mkdir samplepage
```

You can either clone the [samplepage](https://github.com/Roseline-Bassey/Vagrant-Project) folder from GitHub or use your preferred web page content.

Run the following commands:
``` 
vagrant ssh web01
``` 
to move inside the virtual machine.
Inside the virtual machine, run the following:

```
cd /vagrant
ls
sudo cp -r /vagrant/samplepage/* /var/www/html/
```
When you start a Vagrant virtual machine, a shared folder is created between the two machines, which is mapped to the `/vagrant` directory in the guest machine. Any files or directories placed in your project directory on the host machine are automatically synced to the `/vagrant` directory in the guest machine. This means that Vagrant shares our project folder (myproject) with the guest machine so we can access it from within the VM.

In the code above: 

- `cd /vagrant` - This command changes the current working directory to /vagrant.
- `ls` - This command lists and displays the names of all files and directories in the current directory.
- `sudo cp -r /vagrant/samplepage/* /var/www/html/` - This command copies all files and directories inside the `/vagrant/samplepage/` directory to the `/var/www/html/` directory.

_I had changed my IP address from 192.168.56.18 to 192.168.56.19 when I encountered an error that says: 'The specified host network collides with a non-hostonly network! This will cause your specified IP to be inaccessible. Please change the IP or name of your host only network so that it no longer matches that of a bridged or non-hostonly network.' You do not have to do this excerpt you had the same issue when trying to vagrant up._

![web page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8p8b478jatkvmn4clzr0.png)

If you've made it this far, you should be proud of your accomplishments. You may view the demo web page by clicking [here](https://tranquil-gumption-58f2c5.netlify.app/).

The next step is to automate this process so we don't have to manually provision the web server every time we execute 'vagrant up'. 
 

## Vagrant Automation
In this section, we'll automate the entire process of setting up a virtual machine, installing a web server, and replacing the default Nginx web page with our actual web page. When we execute `vagrant up`, our VM and Nginx web server will be provisioned automatically. To do this, we will write a bash script that will launch our virtual machine automatically.

Create a new file called nginx.sh and add the following code to it:
 
```sh
# installing nginx and copying file
apt update
apt install nginx -y
cp -r /vagrant/samplepage/* /var/www/html/

#starting nginx web server
systemctl start nginx
systemctl enable nginx
systemctl restart nginx
```

Then, in your Vagrantfile, add the following code:
```ruby
web01.vm.provision "shell", path: "nginx.sh" 
```
This code tells Vagrantfile to run a shell script named "nginx.sh" as part of its setup process.

## Validate your Vagrantfile
To check that our Vagrantfile works as expected, we will validate it with 
```
vagrant validate
``` 
_This command should be executed outside of the ssh terminal._
You should see an output like: “Vagrantfile validated successfully.” 

Run `vagrant destroy` to destroy the existing machine and ` vagrant up`  to start the VM with the automated configuration.

Great job! You can now view your web page on the browser using the same IP address you specified in the Vagrantfile. 

## Conclusion
To summarize, you’ve learned how to create a virtual machine and install Nginx on it. Provision a VM that runs a web server both manually and automatically. If you enjoy DevOps and Cloud computing tutorials, please hit the follow button and stop by frequently.