Develop A Website Using Multipass Virtual Machine
Tags: webdev, nginx, ubuntu, vm
Published: 2022-09-25 16:28:13

If you read the previous article in this series, [Create An Ubuntu Virtual Machine with Multipass](https://dev.to/micmath/create-an-ubuntu-virtual-machine-with-multipass-iak), you should now have a fresh Ubuntu instance running as a virtual machine on your Mac. In this article we will set up a quick development environment to allow us to build and test a website.

## Install the Web Server

We will use nginx as our web server. We have a new Ubuntu virtual machine to run it on, so let's open a shell connection and run the installation steps.

First decide which VM instance you want to connect to, use `multipass ls` to get a list of all your instances. Note the name of the instance, and check that it is running. In my case I will connect to my instance named `vm-ubuntu20`.

Use the `multipass sh` command to open a shell connection.

```
% multipass sh vm-ubuntu20
  Welcome to Ubuntu 20.04.5 LTS (GNU/Linux 5.4.0-126-generic aarch64)
  ...
```

Now run the standard commands to install the `nginx` software package. (Note that these commands are running in your virtual machine, so no software will be installed on your real machine.)

```
$ sudo apt update
$ sudo apt install nginx
```

You should now have an nginx web server running on your virtual machine. Refer back to the output of `multipass ls` and you will see the IP address of your instance. In my case the IPV4 is `192.168.64.2` so I can now go to `http://192.168.64.2` in a web browser on my real machine and see the default "Welcome to nginx!" holding page.

## Mount Your Working Folder to Your VM Server

My goal is to use my real machine to build and edit the files used in my website, meaning the work will happen in my MacOS environment, but then to have that folder served from the web server running on the virtual machine. To accomplish this I will share my local working folder with the virtual machine, so that the files there are available to both machines. I will use the `multipass mount` command to  share my working folder, at `~/workspace/vm-ubuntu20/app`, with the virtual machine folder at `/var/www/app`.

```
% multipass mount ~/workspace/vm-ubuntu20/app vm-ubuntu20:/var/www/app
```

## Add Some App Files

Now whatever files we create in `~/workspace/vm-ubuntu20/app` will also be available to the virtual machine instance named "vm-ubuntu20" in the `/var/www/app` folder. For example, if I create a simple `index.html` file in `~/workspace/vm-ubuntu20/app` and then use `multipass sh` to connect to my virtual machine instance, I see that same file appears at `/var/www/app/index.html`.

## Configure the Nginx Host

We need to tell nginx about this new website we want it to serve for us from the `/var/www/app` folder. From a shell connected to the virtual machine instance, we crate a new nginx configuration file.

```
$ sudo vim /etc/nginx/sites-available/app
```

The contents of that file are shown below:

```
server {
    listen 80;
    listen [::]:80;

    server_name app.test;

    root /var/www/app;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}
```

This means that nginx will serve files from `/var/www/app` – our mounted folder that is shared in our workspace – for any requests that have the domain name "app.test". Of course app.test is not a real domain, which is the point, we are only using that as a placeholder for our local development version of the site.

We added the new configuration to the `sites-available` folder but we have to create a link for this new file in the `sites-enabled` folder too: 

```
$ sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
```

And whenever a configuration is changed in nginx, we must tell it to reload those configuration files.

```
$ sudo service nginx configtest
  [OK]
$ sudo systemctl reload nginx
```

## Configure Your Domain Name Resolution

We now need to tell our real machine about this new domain name we just invented and configure it to send requests for that domain name to the IP address of our virtual machine (which recall you can find by using `multipass ls`). This is done by adding a new line to the `/etc/hosts` file on your real machine. In my case that line looks like this:

```
192.168.64.2    app.test
```

Now, when I enter "app.test" into the web browser on my real machine, it directs that request to `192.168.64.2`, as specified in my `/etc/hosts`, which is handled by the nginx server on my virtual machine, which is configured to return files from the virtual machine folder at `/var/www/app`, which is mounted to a shared folder in my real machine's workspace at `~/workspace/vm-ubuntu20/app`.

Whew! That's an admittedly circuitous way to get there but in the end we have created a development environment for building a website using our Mac desktop for editing files whilst serving those files from an Ubuntu virtual server.