Apache

Description

Tips and guides for hosting Plone with Apache web server.

Introduction

Here are useful information and snippets when hosting Plone behind Apache.

Procedure to restart Apache in production enviroment

You might share the same Apache web server across several production sites. You don't want to hinder the performance of the other sites when doing Apache configuration changes to one site.

The correct procedure to restart Apache is (on Ubuntu/Debian Linux)

# Check that config files are working after editing them
apache2ctl configtest

# Let Apache finish serving all the on-going requests before
# restarting worker processes
apache2ctl graceful

www-redirects

If you wish to force people to use your site with or without www prefix you can use the rules below. Note that setting this kind of rule is very useful from the search engine optimizatin point of view also.

Example in <VirtualHost> section to redicte www.site.com -> site.com:

<VirtualHost 127.0.0.1:80>

         ServerName site.com
         ServerAlias www.site.com


        <IfModule mod_rewrite.c>
             RewriteEngine On
             RewriteCond %{HTTP_HOST} ^www\.site\.com [NC]
             RewriteRule (.*) http://site.com$1 [L,R=302]

         </IfModule>

Example in <VirtualHost> section to redirect site.com -> www.site.com:

<VirtualHost 127.0.0.1:80>

         ServerName site.com
         ServerAlias www.site.com


        <IfModule mod_rewrite.c>
             RewriteEngine On
             RewriteCond %{HTTP_HOST} ^site\.com [NC]
             RewriteRule (.*) http://www.site.com$1 [L,R=302]
         </IfModule>

Redirecting all the pages to the root of a new site:

RewriteEngine On RewriteRule (.*) http://www.newsite.com [L,R=302]

Migration redirects

To redirect traffic from all pages permanently (301) to the landing page of a new site:

RewriteEngine On
RewriteRule (.*) http://collective-docs.readthedocs.org/ [L,R=301]

Proxying other site under Plone URI space

The following rule can be used to put a static web site to sit in the same URI space with Plone. Put these rules before VirtualHost ProxyPass.

Examples:

ProxyPass /othersite/ http://www.some.other.domain.com/othersite/
ProxyPassReverse /othersite/ http://www.some.other.domain.com/othersite/

Reverse proxy host

By default, host name is correctly delivered from Apache to Plone. Otherwise you might see all your HTTP requests coming from localhost, Apache.

You need:

ProxyPreserveHost On

For more information, see

Redirecting certain URIs to old site

This is useful if you migrate to a Plone from some legacy technology and you still need to have some part of the URI space to point to the old server.

  • Create alternative domain name for the existing old site (e.g. www2)
  • Modify Apache configuration so that URLs still being used are redirected to the old server with alternative name, Put in this rewrite
<location /media>
        RedirectMatch /media/(.*)$ http://www2.site.fi/media/$1
</location>

Caching images

You can force caching of content types on apache

First you need to enable Apache modules:

* mod_headers
  • mod_cache, mod_diskcache
  • mod_expires

On Debian this is:

sudo a2enmod

Then you can add to your virtual host configuration:

# Disk cache configuration
CacheEnable disk /
CacheRoot "/var/cache/yourorganization-production"
CacheLastModifiedFactor 0.1
#CacheDefaultExpire 1
#CacheMaxExpire 7200
CacheDirLength 2

ExpiresActive On
ExpiresByType image/gif A3600
ExpiresByType image/png A3600
ExpiresByType image/image/vnd.microsoft.icon A3600
ExpiresByType image/jpeg A3600
ExpiresByType text/css A3600
ExpiresByType text/javascript A3600
ExpiresByType application/x-javascript A3600

# Create cache headers for downstream caches and browsers,
# needed to enforce HTTPS cache -
# Expires rules above are enough for plain HTTP

# Set environment variable by guessing the content payload based on how URL ends
SetEnvIfNoCase Request_URI "\.(?:gif|jpe?g|png|css|js|ico)$" cache-it

# Force caching of HTTPS resources on the browser end
# http://blog.pluron.com/2008/07/why-you-should.html
Header append Cache-Control public env=cache-it

# This header is only for the debugging
Header append X-Cache-Tagged yes env=cache-it

Warning

Since Apache caches the whole HTTP response, including headers, see cookie implications below.

Todo

Check if we need to do CacheIgnoreHeaders Set-Cookie here.

More info

Testing cache headers

Use UNIX wget command. -S flag will display request headers.

Remember to do different request for HTML, CSS, JS and image payloads - the cache rules might not be the same.

HTTP example:

cd /tmp

wget --cache=off -S http://production.yourorganizationinternational.org/yourorganizationlogotemplate.gif

HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Date: Tue, 09 Mar 2010 12:33:26 GMT
  Server: Apache/2.2.8 (Ubuntu) DAV/2 SVN/1.4.6 mod_python/3.3.1 Python/2.5.2 PHP/5.2.4-2ubuntu5.4 with Suhosin-Patch mod_ssl/2.2.8 OpenSSL/0.9.8g
  Last-Modified: Wed, 25 Nov 2009 06:51:41 GMT
  Content-Length: 4837
  Via: 1.0 production.yourorganizationinternational.org
  Cache-Control: max-age=3600, public
  Expires: Tue, 09 Mar 2010 13:02:29 GMT
  Age: 1857
  Keep-Alive: timeout=15, max=100
  Connection: Keep-Alive
  Content-Type: image/gif
Length: 4837 (4.7K) [image/gif]
Saving to: `yourorganizationlogotemplate.gif.14'

HTTPS example:

cd /tmp
wget --cache=off --no-check-certificate -S https://production.yourorganizationinternational.org/

Flushing cache

Manually cleaning Apache disk cache:

sudo -i
cd /var/cache/yoursite
rm -rf *

Custom 500 internal error page

To make you look more pro when you update the server or Plone goes down

Load balanced Apache virtual host configuration

This complex config example includes

  • HTTPS and SSL certificate set-up
  • Load balancing using ZEO front-ends and Apache load balancer module
  • Apache disk cache. This should provide static resource caching w/HTTPS support if you are using plone.app.caching.
  • Server site https://production.yourorganization.org

See

More information about how to set a sticky session cookie if you need to support Zope sessions in your code

Example:

<VirtualHost 123.123.123:443>

  ServerName  production.yourorganization.org
  ServerAdmin rocks@mfabrik.com

  SSLEngine On
  SSLCertificateFile /etc/apache2/ssl-keys/yourorganization.org.cer
  SSLCertificateKeyFile /etc/apache2/ssl-keys/yourorganization.org.key
  SSLCertificateChainFile /etc/apache2/ssl-keys/InstantValidationCertChain.crt

  LogFormat       combined
  TransferLog     /var/log/apache2/production.yourorganization.org.log

  <IfModule mod_proxy.c>
   ProxyVia On

   # prevent the webserver from being used as proxy
   <LocationMatch "^[^/]">
     Deny from all
   </LocationMatch>
  </IfModule>

  # Balance load between 4 ZEO front-ends
  <Proxy balancer://lbyourorganization>
    BalancerMember http://127.0.0.1:13001/
    BalancerMember http://127.0.0.1:13002/
    BalancerMember http://127.0.0.1:13003/
    BalancerMember http://127.0.0.1:13004/
  </Proxy>

  # Note: You might want to disable this URL of being public
  # as it can be used to access Apache live settings
  <Location /balancer-manager>
    SetHandler balancer-manager
    Order Deny,Allow
    # Your trusted IP addresses
    Allow from 123.123.123.123
  </Location>

  ProxyPass /balancer-manager !
  ProxyPass             / balancer://lbyourorganization/http://localhost/VirtualHostBase/https/production.yourorganization.org:443/yourorganization_plone_site/VirtualHostRoot/
  ProxyPassReverse      / balancer://lbyourorganization/http://localhost/VirtualHostBase/https/production.yourorganization.org:443/yourorganization_plone_site/VirtualHostRoot/

  # Disk cache configuration
  CacheEnable disk /
  # Must point to www-data writable directly which depends on OS
  CacheRoot "/var/cache/yourorganization-production"
  CacheLastModifiedFactor 0.1

  # Debug header flags all requests coming from this server
  Header append X-YourOrganization-Production yes

</VirtualHost>



Edit this document

The source code of this file is hosted on GitHub. Everyone can update and fix errors in this document with few clicks - no downloads needed.

  1. Go to Apache on GitHub.
  2. Press Fork and edit this file button.
  3. Edit file contents using GitHub's text editor in your web browserm
  4. Fill in the Commit message text box at the end of the page telling why you did the changes. Press Propose file change button next to it when done.
  5. On Send a pull request page you don't need to fill in text anymore. Just press Send pull request button.
  6. Your changes are now queued for review under project's Pull requests tab on Github.

For basic information about updating this manual and Sphinx format please see Writing and updating the manual guide.