echo $RANDOM > ~/Dropbox/fstrigger/deploy

If I run the command above on my machine, what does it do?

- It will write a random number to a file, duh.

Ok, it does that. But it also causes the FreedomSponsors application to update itself from git. About 20 seconds later, I get an email from the server with the deployment logs.
No need to ssh into the server anymore, yay :-)

Now the whole story…

While I was configuring uwsgi for FreedomSponsors (more info in the previous post), I learned about uwsgi emperor mode. From the awesome uwsgi tutorial:

uWSGI can run in ‘emperor’ mode. In this mode it keeps an eye on a directory of uWSGI config files, and will spawn instances (‘vassals’) for each one it finds.
Whenever a config file is amended, the emperor will automatically restart the vassal.

I really liked the way this emperor mode worked, because when I change the python code, there’s no need to restart the web server. I just need to “touch” the uwsgi config file:

touch ~/frespo_uwsgi.ini

This is what gave me the idea to remotely trigger the deployments to FreedomSponsors using Dropbox.

This is how it works:

1) The server has Dropbox installed, and it has its own dropbox account.
2) That Dropbox account has a “fstrigger” directory, which is shared with my personal Dropbox account.
3) The server monitors the file: ~/Dropbox/fstrigger/deploy, so that any changes to it will trigger the deployment script
4) The deployment script:
- updates the code from git
- perform a database backup
- install the new code and respawn the uwsgi workers (by touching the uwsgi config file)
- sends an email with the deployment log to me.
5) After I push some code to git, all I have to do to make it go to production is to change the contents of ~/Dropbox/fstrigger/deploy (on my machine). Dropbox sync will kick in and trigger the deploy on the server.

Cool huh :-)
I can imagine an entire farm of servers self updating simultaneosly with a similar setup.

So, if you want to reproduce this setup, here’s a few tips:

Install the command line version of Dropbox on your server.

The instructions here should be enough:

You may need to edit your /etc/rc.local to make sure Dropbox will run at boot time.
Here’s what it looks like in our server:

sudo -u frespo /opt/dropbox-dist/dropboxd &

Now you need something to monitor file changes.


There’s a tool for that:

apt-get install incron
# But don't do this yet

This is a unix service like cron – the difference is you can bind scripts to file events.
After installed, you can

incrontab -e
# edit the incron table
incrontab -l
# show the incron table

There’s a problem though.
During my testes with incron, the script would trigger if I changed the file locally (on the server), but it wouldn’t trigger when the file changed via Dropbox. I have no idea why (maybe I should file a bug for that)

But then there’s inotify-tools

apt-get install inotify-tools

This is a package with a inotifywait utility command that waits for file events.
(And this I could get to work over Dropbox file changes)
So, I have a script like:

while inotifywait /home/frespo/Dropbox/fstrigger/deploy; do

And, I also put that on /etc/rc.local:

sudo -u frespo /home/frespo/ &

And there you have it! A Dropbox-triggered self updating website :-)

If you have any comments to improve our production environment, please let us know in the comments below!