Some Vagrant Gotchas

I really like Vagrant because it lets you isolate your dev environment from your workstation. I personally think you should always take the time to do this, it's just the right way to do things, especially if you work in a team. If you have never looked at Vagrant, I strongly suggest that you have a look now.

Vagrant helps you to create and provision virtual machines that contain your dev environment. Those machines should:

  1. Be as close to your production server as possible
  2. get to the right state fully automatically, so you can reproduce your env anywhere anytime with one command.

Now I won't repeat stuff that you can read up in the doc, but there are some things I've learned that are not that prominently out there. If you have never worked with Vagrant, first read the doc, then come back to this article.

Provisioning

You have to provision your machine somehow, and the logical choice is to use the provisioner you already know well.

If you don't know one well, I would highly encourage you to use ansible. In my opinion it's the most easy to use for people who don't do sys-admin stuff all the time because it doesn't abstract as much as puppet or salt or chef.

It provisions via yaml files, that defines sequentially executed statements like so:

---
- name: "upgrade"
  apt: update_cache=yes

- name: "locale file"
  copy: |
    src=locale
    dest=/etc/default/locale
    owner=root
    group=root
    mode=0644
  notify: update locale


- name: add system packages
  apt: "pkg={{ item }} state=latest"
  with_items:
    - git
    - sendmail
    - python-dev
    - python-setuptools
    - python-pip
    - htop
    - unzip


- include: users.yml
- include: ssh.yml

which is as close as you can get to the actual command-line commands while still having the power of a provisioner.

If you want to provision a Vagrant machine via ansible, the best way I figured out is this:

Have a shell file that installs ansible on your virgin vagrant machine, then executes your vagrant script like so:

if [ ! -f /home/vagrant/ansible_installed.lock ]
then
    sudo apt-get update
    sudo apt-get install python-software-properties --yes
    sudo apt-add-repository ppa:rquillo/ansible
    sudo apt-get update
    sudo apt-get install ansible --yes
    echo 'ansible installed' > /home/vagrant/ansible_installed.lock
fi
sudo ansible-playbook /ansible/dev.yml -i /ansible/dev_inventory --connection=local

you can then call this script in your Vagrantfile like so:

    concat_dev.vm.provision :shell,
          :inline => "sh /ansible/provision.sh"

Synced Folders

Synced folders are really cool, but they are also the weak point of Vagrant, because they have platform-specific behavior. I think I solved most the Problems for Windows, I'm sure there are more for Unix systems.

Permissions

If you do frontend web development, you probably want to execute stuff in your synced folders. Don't try chmod it doesn't work in synced folders. You need to set the permissions in your Vagrantfile like so:

config.vm.synced_folder ".", "/vagrant", :mount_options => ["dmode=777","fmode=766"]

If you provision with ansible, then you are out of luck, because ansible doesn't like the execution rights, so you have no choice but mounting ansible on a different folder with read-write permissions only:

config.vm.synced_folder ".ansible", "/ansible", :mount_options => ["dmode=777","fmode=666"]

Symlinks and node.js

On Windows, symlinks don't work on your synced folder. npm install sometimes wants to link some bins to your local install. So you need to do this:

npm install --no-bin-links

When you want install your node.js dependencies

Compass, Vagrant and Windows

If you use the above three together, I found that you are in for some trouble. You will get weird "file in use" errors when you run compass tasks that want to write new files to a synced folder.

For some Compass versions, I had success with disabling the Sass cache, but for other versions, I found no other way than making Compass compile css to a non synced folder and then copy over the files to their destination (use Grunt or, if you belong to the "cool" guys, the newer gulp to do this)

I'm not sure if these problems still exist with the latest releases of Compass, but if you encounter them and don't want to spend a considerable amount of time problem solving, just hack around it.

Webserver issues

You will probably use nginx or apache. Now there is a stupid quirk with serving static content from a synced folder. It can happen that nginx or apache doesn't notice when files change on your synced folder. For this to work you need change the sendfile variable to "off" in your webserver config. This will fix the issue. See https://coderwall.com/p/ztskha

Making your own Base Box

You can make your own base vagrant box (although most of the time, the images provided by vagrant will be sufficient). Out of all the blogposts out there, I found this to be the most helpful.

comments powered by Disqus