Enabling gzip on apache to send compressed data
This article is part of a series on Installing a ruby on rails application using phusion passenger on ubuntu on slicehost .
Browser should receive compressed data from server. I have been running my blog for years and ,all this while, I had not configured apache to send compressed data. Let’s fix it.
Determining if server is sending compressed data
First task is to find out if server is sending compressed data or not.
curl --header 'accept-encoding: gzip' http://www.neeraj.name/blog
I see plain text. That means data sent by server is not compressed. In contrast try this and you will see garbled text.
curl --header 'accept-encoding: gzip' http://stackoverflow.com
My configuration
All the tricks I am discussing here are tested on my machine which has following configuration.
> cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=8.04 DISTRIB_CODENAME=hardy DISTRIB_DESCRIPTION="Ubuntu 8.04.1"
Apache version
> apache2 -v Server version: Apache/2.2.8 (Ubuntu) Server built: Jun 25 2008 13:54:43
mod_deflate
mod_deflate is an apache module that makes it possible to send compressed data. First task at hand is to find out if apache is loading this module or not.
> apache2 -l Compiled in modules: core.c mod_log_config.c mod_logio.c prefork.c http_core.c mod_so.c
As you can see, current configuration of apache does not load mod_deflate.
I need to find out if deflate is available as a module or not.
> cd /etc/apache2/ > ls mods-available | grep deflate deflate.conf deflate.load
OK. deflate module is available. I have following lines of code in my apache2.conf .
# Include module configuration: Include /etc/apache2/mods-enabled/*.load Include /etc/apache2/mods-enabled/*.conf
mods_enabled directory is nothing else but symlinks to files in mods_enabled directory.
> ls -ltr mods-enabled/ total 0 lrwxrwxrwx 1 root root 29 2009-05-31 14:08 status.load -> ../mods-available/status.load lrwxrwxrwx 1 root root 29 2009-05-31 14:08 status.conf -> ../mods-available/status.conf
To enable mod_deflate, all I need to do is to put a similar symlink.
cd mods-enabled sudo ln -s ../mods-available/deflate.conf deflate.conf sudo ln -s ../mods-available/deflate.load deflate.load
Now reload apache configuration
sudo /etc/init.d/apache2 reload
Now when I try below mentioned command, I get garbled text. It means I am getting compressed data.
curl --header 'accept-encoding: gzip' http://www.neeraj.name/blog
Also try —compressed option and you should see Content-Encoding as ‘gzip’.
> curl --head --compressed http://www.neeraj.name/blog HTTP/1.1 200 OK Date: Thu, 27 Aug 2009 00:39:38 GMT Server: Apache/2.2.8 (Ubuntu) Phusion_Passenger/2.2.4 Last-Modified: Thu, 27 Aug 2009 00:29:18 GMT ETag: "c0a84-569a-47214a8751380"-gzip Accept-Ranges: bytes Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 6524 Content-Type: text/html
Server configuration
Although you are getting compressed output and apache recommends that you explicitly put directive to compress the output. I am using vhost and this is what a typical vhost for me looks like
<VirtualHost xx.xx.xx.xx:80>
ServerName xxxx
ServerAlias xxxxx
DocumentRoot /home/xxx/current/public
<Directory "/home/xxxx/current/public">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
After adding the location tag as per apache guidelines , it looks like this
<VirtualHost xx.xx.xx.xx:80>
ServerName xxxx
ServerAlias xxxxx
DocumentRoot /home/xxx/current/public
<Directory "/home/xxxx/current/public">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<Location />
# Insert filter
SetOutputFilter DEFLATE
# 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 \bMSIE !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI \
\.(?:gif|jpe?g|png)$ no-gzip dont-vary
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</Location>
</VirtualHost>
Reload apache.
sudo /etc/init.d/apache2 reload
I got following error.
Invalid command 'Header', perhaps misspelled or defined by a module not included in the server configuration ...fail!
That is because headers module is missing. Fixing that is easy.
cd mods-enabled sudo ln -s ../mods-available/headers.load headers.load
Now reload apache and it works fine.