Quick tip when using vagrant+django

I started to use vagrant to hold my development environment, it helps to keep the development environment isolated, since the app will run on a Linux server, with a specific database engine and probably some other specific modules, I don’t want to clutter my OS with all that stuff. More if I plan to work on another project that maybe, have a dependency on other versions of the same base (legacy Django perhaps?)

So, Django… Django have a nice mechanism that helps development, you don’t need a running web server to try your project. No need to have Apache/NGINX for that, and better yet, every time you update a python file it reloads the module so you always have reflected your changes.

But there is a catch, Django (by default, or by itself) always polls every file in the project to know which file has changed, with small projects there is no problem, it’s quite fast, but when you have a bunch of files you can spend a considerable amount of CPU  (around 6% ) just polling. Not nice, and is worst if you are in a VM (vagrant).

A better way to do this is using py-inotify, with this Django will not be polling, just wait until the watcher notifies about a file change, then it reloads. So, using py-inotify reduces the CPU time spent just in polling.

But… Vagrant shares the source code folder (and other folder if you set them up) with the VM via NFS. NFS was implemented like 30 years ago and they sure didn’t took in mind inotify (it didn’t exist at that time), so, if you update the code NFS will not set the notification in the kernel, and py-inotify will never knew there was a change, so Django will not reload ?.

How to fix it?

Turns out its pretty simple, just install a vagrant plugin to forward the notification via vagrant.

vagrant plugin install vagrant-notify-forwarder

Then shutdown and up your VM in order to get the plugin and forwarder service started, and it’s ready.