Last time, I talked about finding a pre-made vagrant box that would be useful for rails development. I found one that’s pretty good, but it turns out not to be perfect. I decided to try to write my own Vagrantfile for getting a simpl rails server running on localhost, and I came up with the following success criterion:
No care or feeding. In other words, I could open the vagrant file, and run the following commands straight through and have them just work:
vagrant up --provision
vagrant ssh
cd /vagrant
rails new toy_app
cd toy_app
rails server
And then in the host machine, browsing to localhost:3000
should show the standard “hello from rails” screen. Anything less than that and I feel like I’m sacrificing the real benefit of Vagrant, namely, a repeatable, portable environment setup.
I am doing this by iterative experiment. I started with a Vagrantfile that was empty except for setting the base image of ubuntu/trusty64
.
Each iteration, I run vagrant up --provision
, then ssh into the box, then try to start a rails server. If I get an error (or am missing a dependency), I exit the ssh session, edit the Vagrantfile, and reload the vm. Periodically, I destroy the vm to make sure that I’m not dependent on some sequence of shell commands I happened to run.
One thing I’ve found useful is this command:
cp $HISTFILE /vagrant/history.txt
It copies the list of shell commands that I’ve run (since the last time I destroyed the vm) into the shared folder, so I can access them from the host machine. That way, if I manage to do something important while I’m ssh’ed into the box, I can read the steps carefully when I’m trying to figure out how to add them to the Vagrantfile so that they become a repeatable part of the environment.
The following Vagrantfile almost passes the test:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- mode: ruby -*- | |
# vi: set ft=ruby : | |
# All Vagrant configuration is done below. The "2" in Vagrant.configure | |
# configures the configuration version (we support older styles for | |
# backwards compatibility). Please don't change it unless you know what | |
# you're doing. | |
Vagrant.configure("2") do |config| | |
config.vm.box = "ubuntu/trusty64" | |
config.vm.network "forwarded_port", guest: 3000, host: 3000 | |
# runs as root | |
config.vm.provision "shell", inline: <<-SHELL | |
apt-get update | |
git –version || apt-get install -y git | |
rails –version || apt-get install -y ruby-railties-4.0 | |
nodejs –version || apt-get install -y nodejs | |
SHELL | |
# runs as non-root user "vagrant" | |
config.vm.provision "shell", privileged: false, inline: <<-SCRIPT | |
gpg –keyserver hkp://keys.gnupg.net –recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 | |
curl -sSL https://get.rvm.io | bash -s stable –rails | |
source /home/vagrant/.rvm/scripts/rvm | |
rbenv install 2.0.0-p353 | |
rbenv global 2.0.0-p353 | |
yes | gem update | |
gem install rdoc | |
gem install rails pg | |
if [ ! -d "/vagrant/toy_app" ]; then | |
(cd /vagrant && rails new toy_app) | |
fi | |
(cd /vagrant/toy_app && bundle install) | |
SCRIPT | |
end | |
What it’s still missing is that rails server
doesn’t quite do what it should; for some reason, running rails server
will launch the rails server just fine, but will not enable port forwarding, and for that I need to run bundle exec puma -C config/puma.rb
. Next time, I’ll try to figure out why the default commands executed by rails ignore config/puma.rb
. Also, there are a few warnings printed to the terminal when I vagrant up -- provision
from that file. I haven’t noticed any ill effects yet, but I might still try to chase down the errors in a future post.
Till next time, happy learning!
-Will