Configuring the Apache HTTP Server

= Apache Configuration Checklist =


 * Redirect non-www to www (or the other way around).


 * Redirect non-https to https.


 * Enable gzip compression.


 * Optimise caching.


 * Check that HTTP/2 works. In Firefox's Inspector, Network tab, look for an X-Firefox-Spdy: "h2" response header.

Redirection
You will normally want to redirect non-www to www (or the other way around, depending on your preference), and non-https to https (for general privacy and legal data protection requirements).

If you have administrative access to the server, it is better to setup such redirections in the server configuration files. See the "When not to use mod_rewrite" documentation page, and the RedirectSSL Recipe among others in the Apache HTTP Server Wiki. You may also want to look into HTTP Strict Transport Security.

If you are a client on a hosting server and have no administrative access, then you can achieve those redirections with the following lines in an .htaccess file: RewriteEngine On RewriteCond %{HTTP_HOST} !^www\. [nocase] RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI}  [last,redirect=301,noescape] RewriteCond %{HTTP:X-Forwarded-Proto} =http [ornext] RewriteCond %{HTTP:X-Forwarded-Proto} ="" RewriteCond %{HTTPS} !=on RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI}  [last,redirect=301,noescape]
 * 1) Redirect from non-www to www, and at the same time to https.
 * 1) Redirect from all other "http://www.blahblah" to https.

The configuration above is using 301 (moved permanently) redirects, which may be too permanent, because some web browsers cache them indefinitely. One could argue that a 302 "temporary" redirect may be safer. Who knows if you will no longer always want to use https in the future for some unforeseen reason. However, there are many other aspects to consider when choosing a redirect type, such as performance and the impact on web search results.

The above rules are actually not such a good idea, because such automatic redirections means that non-encrypted requests may remain unnoticed for a long time. It is best to let non-https requests fail hard and fast. That would force everybody to update their links, which helps prevent unintended data leakage. If you can help me improve the rules above, please drop me a line.

Enable gzip Compression
Add the following to your .htaccess file:

  AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript  

Notes:
 * Without further tricks, Apache recompresses the files every time (there is no compressed file cache). Therefore, using compression increases server CPU usage. If this is a problem, you can also try with setting "DeflateCompressionLevel 1".
 * mod_deflate and mod_fastcgi (for FastCGI) do not coexist well under certain versions of Apache.
 * The alternative mod_gzip is older and no longer recommended.

Optimise Caching
Note that HTTP header If-Modified-Since optimises full file downloads away by default. That is enough for most purposes.

If you want to optimise even the If-Modified-Since queries away, you can use the following lines in your .htaccess file. But beware that this may prevent browsers from downloading updated file versions, so it is best to change the filename every time a file is modified.

 ExpiresActive on ExpiresDefault "access plus 5 minutes" ExpiresByType image/x-icon "access plus 1 year" ExpiresByType image/jpg "access plus 1 month" ExpiresByType image/jpeg "access plus 1 month" ExpiresByType image/gif "access plus 1 month" ExpiresByType image/png "access plus 1 month" ExpiresByType text/html "access plus 4 hours" ExpiresByType text/htm "access plus 4 hours" ExpiresByType text/javascript "access plus 2 days" ExpiresByType text/css       "access plus 2 days" ExpiresByType text/xml       "access plus 2 days" ExpiresByType application/xml "access plus 0 seconds" ExpiresByType application/json "access plus 0 seconds" ExpiresByType text/cache-manifest "access plus 0 seconds" 
 * 1) This is for the favicon.