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
curlthat 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
$ 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:
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
- 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
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
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.
sudo node ..