Development Installing NodeJS in Vagrant on Windows
I’ve almost never come across issues with using Vagrant to emulate a Linux environment, except for one time I was installing NodeJS.
Node’s package manager (npm) makes heavy use of symlinks and that’s one area where Windows falls over. If you’re doing everything inside of the VM, this isn’t an issue, however if you’re using shared folders (e.g. with source control in the host environment), then the symlinks will cause the provisioning to fail.
I’ve attached a sample Vagrantfile which works around that problem by setting the configuration of Virtualbox to allow symlinks. The trick is that the command prompt used when calling ‘vagrant up’ needs to be elevated to administrator privileges.
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "ubuntu/trusty64"
config.vm.network "forwarded_port", guest:80, host: 8080, auto_correct: true
config.vm.provider "virtualbox" do |v|
v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
end
# Uncomment this if you want to link to a shared folder (e.g. if you are running source control and want to link it to Vagrant)
config.vm.synced_folder "./sample-app", "/home/vagrant/sample-app", create: true, group: "vagrant", owner: "vagrant"
config.vm.provision "shell", path: "provision/setup.sh"
end
And below is the Bash provisioning script.
#!/bin/bash
echo "*******************************"
echo "Provisioning virtual machine..."
echo "*******************************"
echo "***********************"
echo "Updating apt sources..."
echo "***********************"
sudo apt-get -qq update
echo "***********************************"
echo "Install and re-link node and npm..."
echo "***********************************"
sudo apt-get -y -qq install build-essential nodejs npm redis-server
sudo npm install -g forever
sudo ln -s "$(which nodejs)" /usr/bin/node
echo "***********************************"
echo "Run npm install and then run app..."
echo "***********************************"
cd sample-app
sudo npm install
sudo forever start server.js
echo "*********************************"
echo "Success! Navigate to localhost..."
echo "*********************************"
I’ve created a
BitBucket repo GitHub
repo which includes a
sample NodeJS app that I found
here.
As a quick note, the provisioning script also includes the installation
of Redis, as that’s what the sample app requires - as well as a symlink
between ‘node’ and ‘nodejs’ to eliminate any problems with npm.
So, to summarize, pull down my repo, open up an elevated (administrator) command prompt, call ‘vagrant up’, and navigate to localhost:8080 and you should see the running NodeJS app!
Note: There is an alternative way to solve this problem, which involves using npm with a no-symlinks flag, but I still found that to be buggy, so I haven’t included that solution.