All Articles

HOWTO: Automatically Enable GZip Compression on AWS Elastic Beanstalk

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).