in Code, Tutorials

Creating a Vagrant Box for Strongloop Development with Ubuntu 16.04 (Xenial)

So I’m working on a mobile app development project which is using Loopback for REST API generation. I wanted to set up a Vagrant box with the following attributes:

  • Use VirtualBox
  • Ubuntu Server 16.04 (Xenial Xerus) x64
  • Latest NodeJs (currently 6.11.3)
  • Strongloop (npm package that installs CLI for working with loopback)

This wasn’t as straightforward as I expected. Here are the steps I took to get it up and running.

Step 1: Install latest VirtualBox and Vagrant

First, grab the latest version of VirtualBox. If you have an older version installed, you can just install the new one using the downloadable installer and it will overwrite the previous version.

Next, grab the latest version of Vagrant. Again, you can just run the installer to overwrite any previously installed version with the latest one.

Step 2: Create a new directory for the box

Personally, I have a dev directory in my home folder where I keep all of my projects, so for me:

$ mkdir ~/dev/vagrant_xenial_strongloop
$ cd ~/dev/vagrant_xenial_strongloop

Step 3: Install and configure the latest Ubuntu

The default install of the Ubuntu Vagrant box doesn’t have enough memory allocated for strongloop to install properly. Here are the steps I had to follow. First, initialize a new box:

$ vagrant init ubuntu/xenial64

Next, in your favorite text editor, you need to update the Vagrantfile (which was created for you in your current folder) so that it has enough memory. In my case, I also configured a “private network” IP address. I’ll explain why I did that later. Here’s what my Vagrantfile looks like with everything but the necessary bits removed:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
  end
end

Once you save this file, you can go back to the terminal and fire up your box:

$ vagrant up --provider virtualbox

NOTE: I found that on one of my machines I had trouble with this command. It appears that for some systems the version of curl that ships with Vagrant doesn’t work. Follow the instructions on this thread to figure out how to replace it with one that works!

Once the box has started, SSH into it:

$ vagrant ssh

Step 4: Install latest NodeJs

I found this handy tutorial at DigitalOcean which described how to do this. Here are the commands:

$ cd ~
$ curl -sL https://deb.nodesource.com/setup_6.x -o nodesource_setup.sh
$ sudo bash nodesource_setup.sh
$ sudo apt-get install nodejs -y
$ sudo apt-get install build-essential -y

Alternatively, if you’d like to install other versions of Node (like the current, non-LTS version) you can find the instructions on the NodeSource website.

Step 5: Install Python2.7 and configure npm to use it

Ubuntu 16.04 comes with Python3 installed but apparently, npm uses the node-gyp package which needs Python2.7.

$ sudo apt-get install python2.7 -y
$ npm config set python /usr/bin/python2.7

Step 6: Change owner of /usr/local and set npm prefix

In order for npm to be able to install everything in /usr/local you need to change its ownership to the default user (not root). You also need to make sure that npm is configured to install packages to /usr/local which, I was surprised to find, was not the default. (In my case the default prefix was /usr.)

$ sudo chown -R $USER:$USER /usr/local
$ npm config set prefix /usr/local

Step 7: Install Strongloop

Finally, we can install Strongloop:

$ npm install -g strongloop

Assuming everything went smoothly, you can test to make sure that Strongloop was installed by typing slc -v at the console. It should print out the version of Strongloop/API Connect that is installed.

Additional Configuration Steps

There are a couple more things you may want to do if you’re setting this up as part of your dev environment.

Associate A Domain Name

I like to create a domain name, e.g. my.supercoolapi.com, and associate it with the IP address I set up in the “private network” setting in the Vagrantfile. That way, I can test out the API in a web browser just by typing in the domain name.

To do this, in a text editor on your host machine, open up the hosts file. On Windows machines, this is located at c:\Windows\System32\drivers\etc\hosts and on OSX/Linux it’s at /etc/hosts. Add a line at the bottom of the file that looks like:

192.168.33.10 my.supercoolapi.com

You can substitute in any domain name that you would like, but be sure that:

  1. The IP address is the same one you set up in the Vagrantfile, and
  2. The domain name you choose is not the same as an actual website that you actually visit, e.g. google.com, because you won’t be able to get to that site anymore.

Sync Dev Directory from the Host to the VirtualBox

Since API development is a lot easier using a GUI editor (I like Sublime Text), it would be nice to be able to edit my loopback API in my host OS and have those changes synced with the files on my virtual machine. This is as simple as adding one line to your Vagrantfile that looks like:

config.vm.synced_folder "/path/to/host/api", "/path/to/vm/api"

You can use absolute or relative paths. It’s easiest to map your code into a subdirectory of the home directory of the virtual machine. The path on the host OS must exist before you start up your VM. It doesn’t matter if the path on the VM exists, and you can create it after you load your VM. In my case, my final Vagrantfile looked like:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/xenial64"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.synced_folder "./api", "/home/ubuntu/api"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
  end
end

To do this, I had to run mkdir api in the same directory as my Vagrantfile before reloading my virtual machine. It also meant that when I generated my loopback API on the VM (using slc loopback), I needed to do so from the home folder and using the directory name api.

Forward Ports to the Host

I wanted to use MongoDB Compass, a GUI tool for analyzing/managing MongoDB databases on my host machine to look at databases on my virtual machine. By default, Mongo runs on port 27017, but when I tried to access it in Compass using my.supercoolapi.com:27017, I got a message saying there was no server there. Fortunately, random geekery came to my rescue, and showed how to alter my configuration to allow Compass to access a Mongo instance running on a virtual machine. First, update your Vagrantfile, adding the following line to your Vagrant.configure block:

config.vm.network "forwarded_port", guest: 27017, host: 27017

Then within your virtual machine, edit the /etc/mongod.conf file, to comment out the bind_ip config setting, so that your Mongo server will listen on all interfaces:

# Listen to local interface only. Comment out to listen on all interfaces.
# bind_ip = 127.0.0.1

Then restart Mongo from the command line with sudo service mongod restart and you should be able to connect.

Run loopback through port 80

After you’ve generated your loopback API app, you can go to ~/api/server/config.json and change the port number to 80. In order to start up the server you’ll have to use sudo, so from the root of your API (i.e. ~/api) run sudo node ..

Conclusion

I really love building API’s with loopback. The whole process runs super smoothly and I like being able to develop the REST API in Javascript just like the rest of my apps. One thing I didn’t do in this tutorial was walk you through how to install a database on the VM, but there are plenty of tutorials for that out there already.

Write a Comment

Comment

  1. Hey Dr. Benton,

    I encountered an error when following your tutorial during the ‘npm install -g strongloop’ step. The error was about a read-only filesystem, and the solution was to stop/destroy the vagrant machine I had previously made, install VirtualBox Extension Pack, and then follow the steps to create/init the vagrant box and re-install everything.

    Just for reference, I’m running Linux Mint 18 (Debian-based, so I assume the logic is the same for Ubuntu hosts).

    Thanks!

Webmentions

  • Setting up an API Testing Server with Ubuntu 16.04, Vagrant, VirtualBox, NodeJs and FeathersJs – Morphatic October 7, 2016

    […] of these steps are identical or updates of steps from this older tutorial. Here are the steps to set this […]