Recently I started experimenting with the AWS fancy deployment system, Elastic Beanstalk. The first thing I noticed was that gzip (mod_deflate) compression was not enabled by default. A quick search revealed that it is indeed not enabled by default for reasons of compatibility.
If you are running a web application (e.g. Django, RoR, etc…) that separates out static resources and asks Apache to serve them directly, you can not rely on your web app to do the compression. We have to enable compression at the web server level in a way that will work even when Amazon updates the configurations files. Luckily, it seems that every Apache module underneath the sun is already preloaded, including mod_deflate. Also, the Elastic Beanstalk developers had the foresight to rely on the conf.d/ pattern for loading additional configuration files so that we do not have to mess with their httpd.conf file.
Taking advantage of the .ebextensions configuration file, we can attach a command to copy over our mod_deflate configuration to the conf.d/ folder.
container_commands:
01_setup_apache:
command: "cp enable_mod_deflate.conf /etc/httpd/conf.d"
Finally, this is the enable_mod_deflate.conf. Make sure the file is somewhere within your git repository and that you update the above path to reflect that. (Also ensure that the file extension is .conf or else Apache will not pick it up.)
# mod_deflate configuration
<IfModule mod_deflate.c>
# Restrict compression to these MIME types
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xml+rss
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE image/png
AddOutputFilterByType DEFLATE image/gif
AddOutputFilterByType DEFLATE image/jpeg
# Level of compression (Highest 9 - Lowest 1)
DeflateCompressionLevel 9
# Netscape 4.x has some problems.
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
<IfModule mod_headers.c>
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>
</IfModule>
There you have it; a fairly quick and easy way to automatically enable gzip compression on AWS Elastic Beanstalk without having to manually configure Apache or mess around with all the servers Elastic Beanstalk will instantiate (remember EB instances are meant to be ephemeral).