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…
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:
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.
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 deployWatch.sh script like:
while inotifywait /home/frespo/Dropbox/fstrigger/deploy; do /home/frespo/deployAndRestart.sh done
And, I also put that on /etc/rc.local:
sudo -u frespo /home/frespo/deployWatch.sh &
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!