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:
- The IP address is the same one you set up in the
Vagrantfile
, and - 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.
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!