<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dan Lynn&#187; images Archives  &#8211; Dan Lynn</title>
	<atom:link href="http://danlynn.com/tag/images/feed/" rel="self" type="application/rss+xml" />
	<link>http://danlynn.com</link>
	<description>Finding adventure in just about everything</description>
	<lastBuildDate>Thu, 17 Jun 2010 16:47:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Serving Grails static content with UI-Performance and Cloud Foundry</title>
		<link>http://danlynn.com/grails/serving-grails-static-content-with-ui-performance-and-cloud-foundry/</link>
		<comments>http://danlynn.com/grails/serving-grails-static-content-with-ui-performance-and-cloud-foundry/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 23:54:18 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[amazon]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[cloud foundry]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ebs]]></category>
		<category><![CDATA[ec2]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[j2ee]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[static content]]></category>
		<category><![CDATA[ui performance]]></category>

		<guid isPermaLink="false">http://danlynn.com/?p=98</guid>
		<description><![CDATA[I am excited about Cloud Foundry. It promises to greatly simplify java application deployment to Amazon&#8217;s Elastic Compute Cloud (EC2). With a few clicks, you can deploy an J2EE application (e.g. Grails) to the container of your choice (Tomcat 5.5, tc Server, and more) on a fresh EC2 Linux instance backed by a MySQL database on Amazon&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I am excited about <a href="http://www.cloudfoundry.com/" target="_blank">Cloud Foundry</a>. It promises to greatly simplify java application deployment to<a href="http://aws.amazon.com/ec2/" target="_blank"> Amazon&#8217;s Elastic Compute Cloud</a> (EC2). With a few clicks, you can deploy an J2EE application (e.g. <a href="http://grails.org/" target="_blank">Grails</a>) to the container of your choice (<a href="http://tomcat.apache.org/" target="_blank">Tomcat 5.5</a>, <a href="http://www.springsource.com/products/tcserver" target="_blank">tc Server</a>, and more) on a fresh EC2 Linux instance backed by a MySQL database on <a href="http://aws.amazon.com/ebs/" target="_blank">Amazon&#8217;s Elastic Block Store</a> (EBS). It doesn&#8217;t get much easier than this. The instance configuration automatically configures your container behind an Apache instance, which gives you some great options for hosting static content or configuring side-by-side application platforms.</p>
<p>I&#8217;ve been using <a href="http://burtbeckwith.com/blog/" target="_blank">Burt Beckwith</a>&#8216;s <a href="http://www.grails.org/plugin/ui-performance" target="_blank">UI Performance</a> plugin for Grails to bundle and compress my static content (images, js, css) during the build, so I can save on outbound bandwith and improve the response time of my application. In order to take advantage of this build-time optimization, <strong>we need to modify the Apache configuration to serve static content instead of proxying those requests to the container.</strong></p>
<ol>
<li><span style="font-family: Courier, monospace">$ grails install-plugin ui-performance</span></li>
<li>Configure your app to use the plugin&#8217;s taglibs and to bundle resources if necessary. (See <a href="http://www.grails.org/plugin/ui-performance" target="_blank">http://www.grails.org/plugin/ui-performance</a>)</li>
<li>Add a handler for the <span style="font-family: Courier, monospace">CreateWarEnd</span> event in your <span style="font-family: Courier, monospace">scripts/Events.groovy</span> file (make one if you don&#8217;t have one). This handler will package all the bundled and gzipped resources into a static zip file that you can upload to Cloud Foundry:
<pre class="brush: groovy;">
eventCreateWarEnd = {warName, stagingDir -&gt;
    def directory = new File(warName).parent

    ant.zip(destfile:&quot;${directory}/static.zip&quot;) {
        fileset(dir:&quot;${stagingDir}&quot;) {
            include name: &quot;images/**&quot;
            include name: &quot;css/**&quot;
            include name: &quot;js/**&quot;
        }
    }
}
</pre>
</li>
<li>Create a &#8220;container initialization script&#8221; for Cloud Foundry to execute when your instance starts up. This script will tell Apache to directly serve the following directories and to add the appropriate Content-Encoding header for content that is already gzipped. The name doesn&#8217;t really matter at this point, but I called mine <span style="font-family: Courier, monospace">proxyexcludes.sh</span>.
<pre class="brush: groovy;">
cat &gt; /etc/httpd/conf.d/_proxyexcludes.conf &lt;&lt;END
ProxyPass /images !
ProxyPass /css !
ProxyPass /js !

SetEnvIf Request_URI &quot;\\.gz\\.(css|js|jpg|gif|png|ico)\$&quot; already_compressed=true
Header set Content-Encoding gzip env=already_compressed
END
</pre>
<p>I found that keeping this file up to date was easier if I just let grails rebuild it every time after the WAR is created. I modified my <span style="font-family: Courier, monospace">eventCreateWarEnd</span> handler to take care of this for me:</p>
<pre class="brush: groovy; highlight: [13,14,15,16,17,18,19,20,21];">
eventCreateWarEnd = {warName, stagingDir -&gt;
    def directory = new File(warName).parent

    ant.zip(destfile:&quot;${directory}/static.zip&quot;) {
        fileset(dir:&quot;${stagingDir}&quot;) {
            include name: &quot;images/**&quot;
            include name: &quot;css/**&quot;
            include name: &quot;js/**&quot;
        }
    }

    ant.echo &quot;Creating Proxy exclusion list: ${directory}/proxyexcludes.sh&quot;
    new File(&quot;${directory}/proxyexcludes.sh&quot;) &lt;&lt; &quot;&quot;&quot;cat &gt; /etc/httpd/conf.d/_proxyexcludes.conf &lt;&lt;END
ProxyPass /images !
ProxyPass /css !
ProxyPass /js !

SetEnvIf Request_URI &quot;\\.gz\\.(css|js|jpg|gif|png|ico)\$&quot; already_compressed=true
Header set Content-Encoding gzip env=already_compressed
END
&quot;&quot;&quot;

}
</pre>
</li>
<li><span style="font-family: Courier, monospace">$ grails war</span></li>
<li>Upload the static.zip file produced during the build as &#8220;static content&#8221; when you upload your app to Cloud Foundry:
<p><div id="attachment_117" class="wp-caption alignnone" style="width: 310px"><a href="http://danlynn.com/wp-content/cloud_foundry_static_content.jpg"><img class="size-medium wp-image-117" title="Cloud Foundry Upload Static Content" src="http://danlynn.com/wp-content/cloud_foundry_static_content-300x58.jpg" alt="" width="300" height="58" /></a><p class="wp-caption-text">Cloud Foundry Upload Static Content</p></div></li>
<li>When creating a deployment, upload your &#8220;proxyexcludes.sh&#8221; container initialization script:
<p><div id="attachment_114" class="wp-caption alignnone" style="width: 310px"><a href="http://danlynn.com/wp-content/cloud_foundry_init_script.jpg"><img class="size-medium wp-image-114" title="Cloud Foundry Deployment" src="http://danlynn.com/wp-content/cloud_foundry_init_script-300x89.jpg" alt="" width="300" height="89" /></a><p class="wp-caption-text">Cloud Foundry Deployment</p></div></li>
<li>Fire up your instance and check out the performance gains!</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://danlynn.com/grails/serving-grails-static-content-with-ui-performance-and-cloud-foundry/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
