Move your htaccess files into your virtualhosts file
Every time your apache accesses a directory, it might be looking for a .htaccess in each of them. Not only in the current directly, but also the parent directories. That’s expensive lookups, especially on cloud based drives, which add network latency and cost expensive performance.
Word on the street is, you don’t want to use .htaccess files
The official recommendation for .htaccess files from the Apache Foundation itself is to not use them, unless you have no other choice – e.g. your host doesn’t allow you to edit virtualhost directives for your website.
So there is no such reason if you have access to such, as .htaccess files are nothing more than what should be written in the virtualhost file itself.
However keeping track of every .htaccess change and implementing it into one huge Virtualhost file would be a nightmare to maintain. So let’s simplify by simply including the .htaccess files into it, and removing the on-load lookups for such by disabling AllowOverride
.
Let’s implement
In order to reduce this overhead on our machines, we have decided to set Apache’s Virtualhost directives to Allowoverride None
and include each .htaccess file in the respective domain configuration files, which you can usually find on debian systems in e.g. /etc/apache2/sites-enabled
.
All you need is do a basic find command in your website folder, such as : find /var/www/websitename|grep '.htaccess'
. An example output might look like the following :
/var/www/www.website.com/wp-content/cache/page_enhanced/.htaccess
/var/www/www.website.com/wp-content/cache/minify/.htaccess
/var/www/www.website.com/wp-content/cache/.htaccess
/var/www/www.website.com/.htaccess
Now let’s add these directives into your virtualhost file at /etc/apache2/sites-enabled/www.website.com
which might look like the following :
<VirtualHost *:8080>
ServerName website.com
ServerAlias www.website.com
ServerAdmin your@email.com
DocumentRoot /var/www/www.website.com/
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory "/var/www/www.website.com/">
Options -Indexes FollowSymLinks MultiViews
AllowOverRide None
Include /var/www/www.website.com/.htaccess
Order allow,deny
allow from all
</Directory>
<Directory "/var/www/www.website.com/wp-content/cache/page_enhanced/">
AllowOverRide None
Include /var/www/www.website.com/wp-content/cache/page_enhanced/.htaccess
</directory>
<Directory "/var/www/www.website.com/wp-content/cache/minify/">
AllowOverRide None
Include /var/www/www.website.com/wp-content/cache/minify/.htaccess
</directory>
<Directory "/var/www/www.website.com/wp-content/cache/">
AllowOverRide None
Include /var/www/www.website.com/wp-content/cache/.htaccess
</directory>
LogLevel warn
ErrorLog ${APACHE_LOG_DIR}/www.website.com-error.log
# Since Apache is running on :8080 with a varnish on :80, let's log the real IP
SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
CustomLog ${APACHE_LOG_DIR}/www.website.com-access.log combined env=!forwarded
CustomLog ${APACHE_LOG_DIR}/www.website.com-access.log proxy env=forwarded
</VirtualHost>
Additionally we have disabled any access to .htaccess files to read only, so websites wouldn’t be able to alter them on their own. In WordPress plugins like W3TC will notify you that they are lacking access, and will ask you to ammend such changes.
Apache2 won’t boot up if .htaccess is suddenly missing
One caveat to consider is to check if all .htaccess files exist when you restart your Apache Webserver. E.g. the Akismet plugin recently removed its .htaccess file in the latest update, which would fail Apache to start.
For that simply ammend your Apache daemon script in /etc/init.d/apache2
with a new function :
apache_test() {
$APACHE2CTL configtest
}
and add it as variable to your daemon in the section starting after case $1 in
like so :
test)
apache_test
;;
Now you will be able to run /etc/init.d/apache2 test
before attempting to stop/start/restart the server. You might want to extend the functionality to automatically check for it before these, and the apache2 daemon has it’s own handling with configtest as well. But it’s always good to doublecheck if changes you did were correct, before relying on automatic handling.
Apache2 will need to be restarted for .htaccess changes to be effective
The biggest caveat in this setup is that Apache has to be restarted after any .htaccess changes have been made, but that is a tolerable adjustment, as such changes should not happen often.
Now we have .htaccess loaded with Apache at server start, and no more additional recursive directory lookups have to be made by Apache for the .htaccess files on each request. That saves disk IO, performance with network drives and cloud providers induces cost savings as well.