I am posting this as a compilation of resources I have come across since the guides out there don't cater for the virtualisation provided by Vagrant and the errors that can occur due to this.
As a result I will reference a lot of material as others have explained and formatted it better than I, while only replacing steps in said material such that it works under Vagrant.
In an actual deployment environment the resources linked are sufficient (this post is only for Vagrant):
You can either use Homebrew or the installers from their respective websites, here and here.
Via Homebrew:
brew cask install vagrant
brew cask install virtualbox
Vagrant boxes are images which are cloned into a virtual machine by Vagrant, we're going to use Ubuntu 14.04 from the Ubuntu repository to create our virtual machine.
vagrant box add ubuntu/trusty64
Vagrants default provider for virtualisation is VirtualBox so we don't have to configure anything on that front. All we need do is create a Vagrantfile in or next to our projects root folder.
Vagrantfile will serve as the 'location marker' for the /vagrant folder inside our virtual machine, as such anything contained in same folder as our Vagrantfile will be accessible inside our virtual machine.Make sure you cd to wherever you want your shared directory to start from, then all we need to do is run vagrant init with our Ubuntu 14.04 image.
vagrant init ubuntu/trusty64
Ta-da! We're now ready to boot and play around in our virtual machine.
To boot and then ssh into our virtual machine we must be in the same directory as our Vagrantfile and run:
vagrant up
vagrant ssh
Now we're ready to install Ruby, Postgres, Rails, Unicorn, and Nginx.
Install rbenv be sure to leave the file as .bash_profile.Update apt-get, then install Postgres and it's dependencies:
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib libpq-dev
cd /vagrant.Create Unicorn Init Script: Copy the supplied configuration, however:
USER will always be vagrant./home from the APP_ROOT path also leaving just /$USER/$APP_NAME.Finally, given that ports under 1024 are privileged on OS X we're going to have to force our Rails application run on something higher so,:
CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D"CMD="cd $APP_ROOT && bundle exec unicorn -c config/unicorn.rb -E $ENV -D -l 0.0.0.0:3000"unicorn.sock so amend the path to server unix:/home/tmp/sockets/unicorn.sock fail_timeout=0;.root configuration line make sure you replace deploy for with vagrant, producing: root /home/vagrant/APPNAME/public;. proxy_pass to http://localhost:3000;.Since we changed the unicorn.sock file location to a folder inside the /tmp/ folder (which will be deleted every time we halt our machine) we're going to have to setup some shell provisions via vagrant to make sure that the command mkdir /tmp/sockets is run every time we issue vagrant up for this project.
Simply add the following under the configure block in your Vagrantfile anywhere you like:
# Create the /tmp/sockets folder we need every time on startup
config.vm.provision "shell",
inline: "mkdir /tmp/sockets"
Now instead of vagrant up we must run vagrant up --provision every time we wish to start our virtual machine and the /tmp/sockets folder will be created for us. If we don't make this folder Unicorn won't start!
At this point you should be able to access your application on http://localhost:8080/tasks provided you have port forwarding setup in your Vagrantfile. Really though, you'll never access your application with a port on the end so we need to port forward and fix this. As mentioned before Vagrant cannot forward to ports under 1024 as they are privileged on OS X. Running Vagrant under sudo does not help either as this privilege isn't passed to the VBoxManage process Vagrant spawns.
As a result we will forward ports 8080 on our host machine to the virtual machine (guest)'s port 80. Similarly, we shall forward all traffic on port 80 of our host machine to port 8080, also on our host machine. This way we can:
localhost on our host machine...localhost:8080 on our host machine...localhost:80 on our guest (virtual) machine.Finally, we can access our application as localhost!
The host machine is your physical machine, the guest is your virtual one. We're going to port forward port 8080 on the host to 80 on the guest.
Vagrantfile and find the line with config.vm.network in it.config.vm.network "forwarded_port", guest: 80, host: 8080
config.vm.network "forwarded_port", guest: 443, host: 8443
You've now port forwarded the default http and https ports from your host machine to the guest.
Now we need to map the host's ports 80 and 443 to the host's ports 8080 and 8443 so that vagrant can pick it up! We're going to use a nifty plugin called vagrant-triggers because we don't want this taking place all the time. We only need it when we're running our Vagrant instance. Using vagrant-triggers will allow us to execute commands on the host according to commands Vagrant is told to execute.
vagrant-triggers by executing the following command in the same directory as your Vagrantfile: vagrant plugin install vagrant-triggers.Vagrantfile inside the configure block, anywhere you like.config.trigger.after [:provision, :up, :reload] do
system('echo "
rdr pass inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080
rdr pass inet proto tcp from any to any port 443 -> 127.0.0.1 port 8443
" | sudo pfctl -ef - > /dev/null 2>&1; echo "==> Fowarding Ports: 80 -> 8080, 443 -> 8443"')
end
config.trigger.after [:halt, :destroy] do
system("sudo pfctl -ef /etc/pf.conf > /dev/null 2>&1; echo '==> Removing Port Forwarding'")
end
Thus, running vagrant up will setup the port mapping and running vagrant halt will remove it.
You can now access your application from http://localhost/tasks.
I hope this guide helps everyone. I had to go through a bit of hassle finding out information as to why this wasn't working under Vagrant specifically.
Huge thanks to DigitalOcean and this community whose members provided content for this guide including links to the pfctl mapping under Yosemite and Unicorn socket configurations.
If you find anything wrong with the guide please message me so I can investigate and amend if required!
Happy coding,
tsujp
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With