I'm currently building an rather complicated server stack (a ruby on rails app) that I want developers to be able to work on without having to install everything themselves. Therefore I use Vagrant to allow them to do that.
The idea is that when you first install the image it will pull the latest sources and installs the dependencies, the sources are exposed by synced folders (a feature built in vagrant) so that developers can commit sources and edit them in their own environment. The Vagrant-box is only for the server.
Synced folder entry in Vagrantfile:
config.vm.synced_folder "gameeso/", "/var/gameeso", :create => "true"
The image is a Ubuntu server with a upstart script (script is executed on boot and only when internet connection is up) that:
-
Pulls the latest development branch from Github (if folder not exists already)
-
Installs the dependencies (this is done by a script)
- Starts the server
All this happens in a synced folder. I had some problems with this approach, mainly that Vagrant clears the synced folder on my guest system.
I solved this issue by adding 'sleep 10' in the upstart script, so it can wait until Vagrant sets up the synced folders.
Ofcourse, this is not a safe way to do it (in case booting takes longer than 10 seconds, though unlikely these days, I'd rather not like to find out ;))
My question is: Is there a better way to let the guest-host (the vagrant image) populate a synced folder?
Ofcourse, many thanks in advance!
Best Answer
Vagrant's built-in provisioning features should be a perfect fit for this. There are a whole bunch of ways you could do it, but the simplest is probably to take the guts of your Upstart script and make them a plain shell script. Then, put one of these blocks in your
Vagrantfile
:Using an "inline" script. Vagrant will copy the contents from the
Vagrantfile
into a script in the/tmp
directory and execute it.Note that the script here is inside a "heredoc", which means that you need to be careful to make sure that the
SCRIPT
token which ends the heredoc is in the right place - i.e. on a line by itself, without extra whitespace. (The link about heredoc above does show a way to allow whitespace, but you need to be careful anyway.)Pointing to a script file. Vagrant will copy this file into the
/tmp
directory and execute it.Note that the path here is relative to the
Vagrantfile
location. However, the file is not executed from that location, so if you need the file to be in a certain directory, you should follow method #3.Using an "inline" script that points to a script file. This way, you can execute a script in a chosen location (in the example below, that's in
/vagrant
after you have done prerequisites likechmod
or setting environment variables.You could also use a provisioning method that works through a "real" deployment and provisioning system, but depending on your requirements that may be overkill.