node.js Logo

How to install node.js with Ubuntu and Vagrant in a synced folder

Recently, I’ve had to work on a project using AngularJS and node.js. Development was eased using a Ubuntu 14.04 virtual machine, through Vagrant. Not a big deal to install, I was saying to myself, except I ran into a ton of errors with my very naïve approach (geez, what an optimistic fool I can be sometimes).

First, the #epic #fail part

Here is my initial Vagrantfile file content, simplified for this blog post (please make sure you have Vagrant installed first):

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.synced_folder ".", "/var/www/project"
end

And here are the shell commands I executed (everything went fine until I tried to install node.js packages such as karma, gulp, or even PhantomJS):

# build guest OS virtual machine from host OS
vagrant up

# connect to guest OS through SSH
vagrant ssh

# update APT repositories before installing anything else
sudo apt-get update

# install node.js and npm the expected way
sudo apt-get install -y nodejs
sudo apt-get install -y npm

# install a node.js package locally in the
# project (prepare to cry like I did shortly after)
cd /var/www/project
npm install karma

And the horror (just a sample):

[...]
npm http 200 https://registry.npmjs.org/connect/-/connect-3.4.0.tgz
npm ERR! error rolling back Error: UNKNOWN, unlink '/var/www/project/node_modules/karma/node_modules/connect/History.md'
npm ERR! error rolling back  karma@0.13.10 { [Error: UNKNOWN, unlink '/var/www/project/node_modules/karma/node_modules/connect/History.md']
npm ERR! error rolling back   errno: -1,
npm ERR! error rolling back   code: 'UNKNOWN',
npm ERR! error rolling back   path: '/var/www/project/node_modules/karma/node_modules/connect/History.md' }
npm ERR! Error: UNKNOWN, symlink '../rimraf/bin.js'
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <npm-@googlegroups.com>

npm ERR! System Linux 3.13.0-46-generic
npm ERR! command "/usr/bin/nodejs" "/usr/bin/npm" "install" "karma"
npm ERR! cwd /var/www/project
npm ERR! node -v v0.10.25
npm ERR! npm -v 1.3.10
npm ERR! path ../rimraf/bin.js
npm ERR! code UNKNOWN
npm ERR! errno -1
npm ERR! Error: ENOENT, open '/var/www/project/node_modules/karma/node_modules/memoizee/methods-plain.js'
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <npm-@googlegroups.com>
[... a lot more lines of pure pain and suffering...]

After almost two days of investigation, I found out the many reasons for these errors:

  • I was working within a synced folder (ie, a directory shared between the host OS and the guest / virtual machine OS)
  • node.js version was 0.10.25 (while there is a 0.12.7 version released, and even a 4.1.1 version!)
  • npm version was 1.3.10 (while there is a version 3.3.6)
  • I was naïve, optimistic, and thinking of a development universe with unicorns and rainbows

Then, the #win

Here is what I’ve had to do to resolve these issues (new shell commands):

# Note: if your host OS is Windows,
# run "vagrant up" in a command-line as administrator
vagrant up

# connect to guest OS through SSH
vagrant ssh

# update APT repositories before installing anything else
sudo apt-get update

# install g++ to compile stuff
sudo apt-get install -y g++

# retrieve nodesource stuff 0.12 to have a node.js version 0.12.7 installed
sudo curl -sL https://deb.nodesource.com/setup_0.12 | sudo sh

# install node.js the usual way (will also install npm this time)
sudo apt-get install -y nodejs

# let's get "node_modules" out of the synced folder
mkdir /home/vagrant/node_modules
cd /var/www/project
ln -s /home/vagrant/node_modules/ node_modules

# install a node.js package locally in the project
npm install karma

What did I do?

  • By running a remote nodesource script and installing g++, I am now able to have a more recent version of node.js (0.12.7) and npm (2.11.3), which are more up-to-date (as of today) and cause less issues with node.js packages. Also, as most of you probably know, node.js was initially invoked through the command “node”, conflicting with another binary with the same name, and as a consequence was later renamed as “nodejs”. The node.js version installed with nodesource makes node.js available through the “node” and “nodejs” commands, resolving issues with a couple of node.js packages (PhantomJS, I’m pointing at you).
  • By creating a symbolic link for “node_modules” to a directory outside of the Vagrant synced folder, I got rid of filesystem failures from the node.js packages.
  • For Windows host users, by running the “vagrant up” command as administrator, I allowed them to create symbolic links in a Vagrant synced folder

Bonus

All of the above commands in a single Vagrantfile, working, free, just for you, because development should always be like unicorns and rainbows:

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.synced_folder ".", "/var/www/project"
  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get install -y g++
    curl -sL https://deb.nodesource.com/setup_0.12 | sh
    apt-get install -y nodejs
    su vagrant
    mkdir /home/vagrant/node_modules
    cd /var/www/project
    ln -s /home/vagrant/node_modules/ node_modules
    npm install karma
  SHELL
end

9 comments

  1. Thanks for this! I didn’t have to struggle for a long time! Your solution of moving the node_modules out of the shared folder fixed everything immediately for me. Very nice!

Leave a Reply

Your email address will not be published. Required fields are marked *