Rails stack recipe
Here is my stab at setting up a Rails stack based on Rails, Mongrel (cluster) Apache2.2 and Proxybalancer.
This example is using The Debian Apache2 recipe and the remotefile definition. I've just renamed the class to "webserver" and added some extras (such as copying all the relevant vhost files to the server and installing cronolog).
I'm trying to switch to templates instead of copying the files, as it usually contains lots of redundant info, but I haven't got time to refactor it yet. Actually I think I'll make a complete railsapp definition and use that instead. I will update this page when I've done it. Until then, I'm just using this in my node definition:
node 'my.rails.node' {
$appname = "railstest"
$sitename = "railstest.example.com"
include railsstack
file { "/etc/apache2/sites-available/${sitename}":
content => template("apache/apache_mongrel"),
}
}
file mongrel.pp:
class mongrel {
include rubygems
package {
[ "mongrel", "mongrel_cluster" ]:
ensure => installed,
provider => "gem",
require => Package["rubygems"];
}
file { "/etc/mongrel_cluster":
ensure => directory,
}
remotefile { "/etc/init.d/mongrel_cluster":
source => "config/apps/mongrel/mongrel_cluster.rc",
mode => "755",
}
service { "mongrel_cluster":
ensure => running,
enable => true,
pattern => "mongrel_rails",
hasrestart => true,
subscribe => File["/etc/mongrel_cluster"],
require => Remotefile["/etc/init.d/mongrel_cluster"],
}
}
file railsstack.pp:
class railsstack {
include webserver
include mongrel
include mysql-server-50
include wwwroot
package {
[ "libmysqlclient15-dev", "ruby1.8-dev", "gcc", "make" ]:
ensure => installed;
[ "mysql", "rails" ]:
ensure => installed,
provider => "gem",
require => Package["rubygems"];
}
webserver::apache_module { [ "proxy_http", "rewrite", "ssl", "proxy_balancer", "deflate" ]: }
remotefile { "/etc/profile":
source => "config/apps/rubygems/etc_profile",
mode => "644",
}
}
file wwwroot.pp:
class wwwroot {
@file { "/srv/www":
ensure => directory,
owner => "www-data",
group => "www-data",
mode => "775",
}
realize File["/srv/www"]
}
file mysql.pp:
class mysql-server-50 {
package { "mysql-server-5.0": }
service { "mysql":
ensure => running,
hasstatus => no,
pattern => "mysqld",
}
}
template apache_mongrel:
# Thanks to Bradley Taylor author of mongrel_cluster and owner of RailsMachine.com for this config
<VirtualHost *:80>
ServerName <%= sitename %>
DocumentRoot /srv/www/<%= appname %>/current/public
<Directory "/srv/www/<%= appname %>/current/public">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
# Configure the cluster member proxy
<IfModule mod_proxy.c>
ProxyRequests Off
<Proxy *>
AddDefaultCharset off
Order deny,allow
Allow from all
</Proxy>
ProxyVia On
</IfModule>
<Proxy balancer://<%= appname %>>
BalancerMember http://127.0.0.1:5000
BalancerMember http://127.0.0.1:5001
BalancerMember http://127.0.0.1:5002
</Proxy>
RewriteEngine On
# If there is a maintenence.html file in your
# public dir all requests will get rerouted to
# this file. This is for use with capistrano
RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ /maintenance.html [L]
# Rewrite index to check for static index.html
RewriteRule ^/$ /index.html [QSA]
# Rewrite to check for Rails cached pages with .html extentions
RewriteRule ^([^.]+)$ $1.html [QSA]
# All dynamic requests get sent to the cluster
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://<%= appname %>%{REQUEST_URI} [P,QSA,L]
# Deflate for clients that support it.
AddOutputFilterByType DEFLATE text/html text/plain text/xml
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# Error and access logs.
ErrorLog "|/usr/bin/cronolog /srv/www/<%= appname %>/logs/%Y/%m/error-%d.log"
CustomLog "|/usr/bin/cronolog /srv/www/<%= appname %>/logs/%Y/%m/access-%d.log" combined
</VirtualHost>
If you have any comments or suggestions, please feel free to contact me on the mailinglist.
/jrisch