This post is only for collaborate with Drupal community. Due to performance reasons I've had to move Apache's directives from .htaccess file in root directory of web application to virtual host file, with the purpose of avoid the load in the access to system file by Apache Web Server.
The hardest part was getting the rewriting URLs to Clean URLs worked but I succeeded.
I want to record this information in order to help those who want to achieve this performance in a production environment as my web server.
- OS, Red Hat Enterprise Linux Server release 5.7 (Tikanga)
- Apache Web Server 2.2.3 (httpd-2.2.3-63.el5_8.1) with MPM Worker
- PHP 5.3.9 (php53u-5.3.9-1.ius.el5)
- CGI: FastCGI (mod_fastcgi 2.4.6)
I start from the fact that Apache Web Server is running in Worker MPM and PHP works fine with this web server correctly through mod_fastcgi.
Then, Apache's directives from .htaccess file:
#
# Apache/PHP/Drupal settings:
#
# Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format)$">
Order allow,deny
</FilesMatch>
# Don't show directory listings for URLs which map to a directory.
Options -Indexes
# Follow symbolic links in this directory.
Options +FollowSymLinks
# Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
# Force simple error message for requests for non-existent favicon.ico.
<Files favicon.ico>
# There is no end quote below, for compatibility with Apache 1.3.
ErrorDocument 404 "The requested file favicon.ico was not found.
</Files>
# Set the default handler.
DirectoryIndex index.php
# Override PHP settings. More in sites/default/settings.php
# but the following cannot be changed at runtime.
# This directives can be commented out because i know that my web server works with mod_fastcgi instead of mod_php. Just make sure that these directivas are set in your php.ini (/etc/php.ini)
# PHP 4, Apache 1.
#<IfModule mod_php4.c>
# php_value magic_quotes_gpc 0
# php_value register_globals 0
# php_value session.auto_start 0
# php_value mbstring.http_input pass
# php_value mbstring.http_output pass
# php_value mbstring.encoding_translation 0
#</IfModule>
# PHP 4, Apache 2.
#<IfModule sapi_apache2.c>
# php_value magic_quotes_gpc 0
# php_value register_globals 0
# php_value session.auto_start 0
# php_value mbstring.http_input pass
# php_value mbstring.http_output pass
# php_value mbstring.encoding_translation 0
#</IfModule>
# PHP 5, Apache 1 and 2.
#<IfModule mod_php5.c>
# php_value magic_quotes_gpc 0
# php_value register_globals 0
# php_value session.auto_start 0
# php_value mbstring.http_input pass
# php_value mbstring.http_output pass
# php_value mbstring.encoding_translation 0
#</IfModule>
# Requires mod_expires to be enabled.
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch \.php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior. This may
# fail if an error occurs early in the bootstrap process, and it may cause
# problems if a non-Drupal PHP file is installed in a subdirectory.
ExpiresActive Off
</FilesMatch>
</IfModule>
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# adapt and uncomment the following:
# RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
# RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment and adapt the following:
# RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
# RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
# Modify the RewriteBase if you are using Drupal in a subdirectory or in a
# VirtualDocumentRoot and the rewrite rules are not working properly.
# For example if your site is at http://example.com/drupal uncomment and
# modify the following line:
# RewriteBase /drupal
#
# If your site is running in a VirtualDocumentRoot at http://example.com/,
# uncomment the following line:
#RewriteBase /
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
</IfModule>
# $Id: .htaccess,v 1.90.2.5 2010/02/02 07:25:22 dries Exp $
can be moved into virtual host file of web application so:
<VirtualHost *:80>
ServerName myownserver.mycompany.com
ServerAdmin myemail@mycompany.com
DocumentRoot /var/www/html/myownserver.mycompany.com
ErrorLog logs/myownserver.mycompany.com-error_log
CustomLog logs/myownserver.mycompany.com-access_log common
LogLevel warn
<IfModule mod_fastcgi.c>
ScriptAlias /fcgi-bin/ /var/www/html/myownserver.mycompany.com/fcgi-bin/
AddHandler php5-fastcgi .php .php5 .php4 .html .htm
Action php5-fastcgi /fcgi-bin/php5-fastcgi.fcgi
</IfModule>
<Directory ~ "^/var/www/html/myownserver.mycompany.com">
#Directives moved from file. Htaccess.
#Set the default handler.
DirectoryIndex index.php
#Directives moved from file. Htaccess.
#Don't show directory listings for URLs which map to a directory.
Options -Indexes
#Directives moved from file. Htaccess.
#Follow symbolic links in this directory.
Options +FollowSymLinks
Options +ExecCGI
#The following directive must be set to None for the DocumentRoot directory of the web application as well as for the /var/www/html directory in the configuration file httpd.conf Apache Web Server.
AllowOverride None
Order deny,allow
Deny from all
Allow from all
#Directives moved from file. Htaccess.
#Protect files and directories from prying eyes.
<FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format)$">
Order allow,deny
</FilesMatch>
#Directives moved from file. Htaccess.
#Force simple error message for requests for non-existent favicon.ico.
#There is no end quote below, for compatibility with Apache 1.3.
<Files favicon.ico>
ErrorDocument 404 "The requested file favicon.ico was not found.
</Files>
#Directives moved from file. Htaccess.
#This directives can be commented out because i know that my web server works with mod_fastcgi instead of mod_php. Just make sure that these directivas are set in your php.ini (/etc/php.ini)
# <IfModule mod_php4.c>
# php_value magic_quotes_gpc 0
# php_value register_globals 0
# php_value session.auto_start 0
# php_value mbstring.http_input pass
# php_value mbstring.http_output pass
# php_value mbstring.encoding_translation 0
# </IfModule>
# <IfModule sapi_apache2.c>
# php_value magic_quotes_gpc 0
# php_value register_globals 0
# php_value session.auto_start 0
# php_value mbstring.http_input pass
# php_value mbstring.http_output pass
# php_value mbstring.encoding_translation 0
# </IfModule>
# <IfModule mod_php5.c>
# php_value magic_quotes_gpc 0
# php_value register_globals 0
# php_value session.auto_start 0
# php_value mbstring.http_input pass
# php_value mbstring.http_output pass
# php_value mbstring.encoding_translation 0
# </IfModule>
#Directives moved from file. Htaccess.
#Requires mod_expires to be enabled.
<IfModule mod_expires.c>
#Enable expirations.
ExpiresActive On
#Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior. This may
# fail if an error occurs early in the bootstrap process, and it may cause
# problems if a non-Drupal PHP file is installed in a subdirectory.
<FilesMatch \.php$>
ExpiresActive Off
</FilesMatch>
</IfModule>
</Directory>
#Directives moved from file. Htaccess.
#Make Drupal handle any 404 errors.
ErrorDocument 404 /index.php
#Directives moved from file. Htaccess.
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
# If your site can be accessed both with and without the 'www.' prefix, you
# can use one of the following settings to redirect users to your preferred
# URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option:
#
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# adapt and uncomment the following:
# RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
# RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]
#
# To redirect all users to access the site WITHOUT the 'www.' prefix,
# (http://www.example.com/... will be redirected to http://example.com/...)
# uncomment and adapt the following:
# RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
# RewriteRule ^(.*)$ http://example.com/$1 [L,R=301]
#Modify the RewriteBase if you are using Drupal in a subdirectory or in a
#VirtualDocumentRoot and the rewrite rules are not working properly.
#For example if your site is at http://example.com/drupal uncomment and
#modify the following line:
# RewriteBase /drupal
#
#If your site is running in a VirtualDocumentRoot at http://example.com/,
#uncomment the following line:
# RewriteBase /
#Directives moved from file. Htaccess.
#Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteCond %{REQUEST_FILENAME} !^/fcgi-bin/php5-fastcgi.fcgi
RewriteRule ^/(.*)$ /index.php?q=$1 [PT,QSA]
</IfModule>
</VirtualHost>
Good luck
Comments
A similar and simpler solution
My company implemented a solution similar to this, but our solution was to include .htaccess files directly from the vhost, which prevents us from having to update the vhost settings whenever there are changes to the Drupal core .htaccess file:
One disadvantage of doing this is that you need to be aware of all .htaccess files that are used for a website. This includes for example, the .htaccess file that exists in a websites "files" directory.
High performance. Moving .htaccess directives to virtual host D7
Thanks for your feedback. Forget clarify that the above instructions are designed to Drupal 6 (D6). Deruitern proposed solution is short and works properly when working with Apache MPM Fork mode instead of Worker mode + mod_fastcgi, which is our case, since it avoids the endless rewriting of requests previously handled by mod_fastcgi script (php5-fastcgi.fcgi). To Drupal 7 (D7) these are the instructions.
Then, Apache's directives from .htaccess file:
can be moved into virtual host file of web application so:
Again I hope that this information is helpful to anyone.
Awesome sauce!
I setup my linode and have been struggling with this for a while. Some people suggest you can simply copy the htaccess file into the config vhost file on Apache, it would bomb.
I see you guys split them up into two different sections. I copied your scripts and they worked perfectly! After a few days of research, finally stumbling across this has been a Godsend!
You guys rock. Thanks again!
There is an easier way
There is an easier way http://groups.drupal.org/node/22864#comment-79155
[EDIT - I tried the above. Site was giving 404s to some requests, though I could access it myself. I did not investigate why, perhaps something to with different user agents. But it is puzzling.]
Digit Professionals specialising in Drupal, WordPress & CiviCRM support for publishers in non-profit and related sectors