[web-devel] Better web app deployment

Michael Snoyman michael at snoyman.com
Fri May 4 16:55:21 CEST 2012

Hi all,

(Note: I originally was going to just send this to the Yesod mailing list,
but frankly, most of the code I'm setting up would work for any web
framework. If people using other frameworks want to use this deployment
code, and are interested in working with me to make sure it's universally
applicable, please be in touch.)

I'm planning on improving the deployment code starting next week. Instead
of comparing to what we currently have (and which I think only I use), let
me just give a high-level approach. Please give input on how you'd like to
change things. Once I have the basic structure put together, I'll put it up
on Github, and contributions will be greatly appreciated:

* We'll use Nginx as a reverse proxy. This will allow us to have virtual
hosting, more efficient static file serving (possibly from a separate
domain), and zero-downtime deployments.
* The scaffolding will accept a number of environment variables for
configuring it, such as PostgreSQL connection information, approot, static
root, and port number. (Most of this is already implemented.)
* Each site will have a deployment configuration file, for things like
domain name, whether a PostgreSQL database is required, and any system
packages are required to be installed (we'll assume a Debian-based system
for now). The deployer will automatically create databases and provide that
information via environment variables.
* Apps will have a specific file format, which is essentially a deployment
config file and a bunch of things (static folder, executable, etc) it
needs. An app will then be a tarball of those folders.
* The deployer will watch a folder for changes. Deployments will be
performed by copying files into this folder.
* When a new app is deployed, it will be unpacked, started up, and
monitored. If it stops, it will be restarted. The Nginx config file will be
updated to reverse proxy to the app's port (randomly assigned) and then
* When a new version of the app is deployed, we'll unpack and start it up
to a new folder with a different port. Once the app responds to an HTTP
HEAD request (doesn't matter *how* it responds), we'll update the Nginx
config file, reload Nginx, send the TERM signal to the old app, and then
delete the old app's folder.
* When an app is deleted, remove it from the Nginx config file, reload
Nginx, send the app the TERM signal, and delete the folder.
* We'll automatically store log files for apps (recommendations on good
approaches here are welcome).
* The deployer itself will provide a web interface to monitor status of
apps and view logs.
* I have no specific plans for running shell scripts or the like. I believe
most of that can be part of the app loading. With the zero-downtime
deployment, it's acceptable for the load time to be significant. If anyone
has better ideas here, let me know.

If we get a good deployment tool going, I think I would next want to set up
an AMI (Amazon Machine Image) to make it dead simple to spin up an instance
capable of hosting Yesod apps. If we can get it to configure DNS as well,
and get a command line tool that automatically performs the EC2 instance
creation, I think we'd be golden.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/web-devel/attachments/20120504/b28221f2/attachment.htm>

More information about the web-devel mailing list