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
Thanks for sharing your experience with us 🙂
Life saver! Thanks
Thank you so much.
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!
Was about to do ‘the #epic #fail’, then found this… Thanks!
If this is going to work, i’m totally gonna buy you all your next year’s coffee cups!
nice work
Thank you so much!!
Great post, most informative, didn’t realise devops were into this.
Saved my life! Thx
Thank you so much. GREAT POST ^^
saved my life, thanks!