I love sharing my adventures in tests and coding as a way to solidify
my learning, but also in the off chance it can help you as well.
This time, I’m going through how to set up Vagrant to provision
processes related to rvm & ruby and nvm & node. The set up allows the
provisioner to even run bundle install or npm install as a
provisioning step.
If you want to step up your vagrant (shell) provisioning to another
level with ruby and node, this is the article for you!
This article will take you about six minutes or less to read as there
are code and vagrant output.
After an embarrassing interview with a candidate where I could not run
our awesome test suite in front of them, I wanted to get our
project running on a automated build system.
For me, this means setting up our system in an automated manner with
Vagrant. I just want to have a consistent environment to work from.
It’s easy to install the system level dependencies, like postgresql or
even ruby.
Next Level Automation
Even with the system level dependencies installed, I want to get the
project’s dependencies installed. Installing nokogiri with native
extensions can feel like forever. I want this process to part of
during Vagrant’s provisioning process.
This is tricky because Vagrant’s provisioning system is basically
scripting out the root user, so installing Ruby management tools like
rvm is not useful, the main user in a Vagrant system
is vagrant.
To get around this, use the privileged:
false
option in the provisioning process. This would be scripting out the
vagrant user instead of root.
rvm & ruby
Even with this option, installing rvm is easy, but using rvm in a
simple script
$ vagrant provision still errors with:
WHY?
The worst part of is: I can manually log in to the machine, run the
same command and it will just work. Why?!
The key: the vagrant provisioner is the vagrant user, but it does
not load up ANY profile information, that include bash - why should
it?!
Before doing any commands to load up ruby, just execute:
Making this change in the above script, the whole script becomes:
This will give results:
Now in the provisioning script, the provisioner can run ruby commands
like bundle, rake, and even rspec!
Now there’s nothing stopping from having a fully built developer
machine with Vagrant!
nvm & node
The issue above with rvm also happens with
nvm, the node
version manager. When nvm is not configured properly in the
provisioner, the following error appears:
Like rvm, trying to have nvm install node in the provisioner returns
an error:
The solution is similar to rvm, load nvm’s configuration into the
provision script, the whole script is:
Now the output is:
Conclusion
In my quest to fully automate vagrant provisioning so a developer box
can be a single step, I learned:
privileged: false runs scripts as the vagrant user.
The privileged: false mode does not load any user settings, like
profiles or paths.
To have the vagrant provisioner run commands that managed services
like rvm or nvm uses, just load the bash profile OR follow its commands.
With this, I am a leap closer to having a fully automated build for
developer boxes.
I can’t wait for the next team member to join to show them how easy it
is to set up our development environment!
I’m always looking for good people to join my team. Even if you’re not
looking for a position now, contact
me to stay in touch, because you
never know!