phpapacheapache2lampmod-cache

Why is Apache2 mod_cache serving a directory index instead of index.php?


I have a multi-site WordPress installation running on a DigitalOcean droplet. I added Apache's mod_cache module to cache content from my website, but I'm running into a really weird issue. On the first page load after I set up the cache, the site loads fine. However, on subsequent page loads I get the directory index instead of index.php getting called:

enter image description here

If I clear the cache, the next page works fine. It seems like mod_cache is caching the directory index HTML page instead of the rendered output of index.php.

Here's my site configuration:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName jeremydormitzer.com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html/jeremydormitzer.com

    ErrorLog /var/log/jeremydormitzer.com/error.log
    CustomLog /var/log/jeremydormitzer.com/access.log combined

    <Directory /var/www/html/jeremydormitzer.com/>
        AllowOverride All
    </Directory>

    RewriteEngine on

    LoadModule cache_module modules/mod_cache.so
    <IfModule mod_cache.c>
        LoadModule cache_disk_module modules/mod_cache_disk.so
        <IfModule mod_cache_disk.c>
            CacheEnable disk /
            CacheDisable /wp-admin
        </IfModule>
        CacheLock on
        CacheLockPath "/tmp/mod_cache-lock"
        CacheLockMaxAge 5
        CacheDisable "http://security.update.server/update-list/"
    </IfModule>

Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/qa.getpterotype.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/qa.getpterotype.com/privkey.pem
</VirtualHost>
</IfModule>

Here's my cache_disk.conf:

<IfModule mod_cache_disk.c>
    CacheRoot /var/cache/apache2/mod_cache_disk
    CacheDirLevels 2
    CacheDirLength 1
</IfModule>

And here's my apache2.conf:

Mutex file:${APACHE_LOCK_DIR} default    
PidFile ${APACHE_PID_FILE}
Timeout 300    
KeepAlive On    
MaxKeepAliveRequests 100    
KeepAliveTimeout 5   
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}    
HostnameLookups Off    
ErrorLog ${APACHE_LOG_DIR}/error.log    
LogLevel warn

IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf    
Include ports.conf

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Require all denied
</Directory>

<Directory /usr/share>
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

<Directory /var/www/html>
    AllowOverride All
</Directory>

AccessFileName .htaccess

<FilesMatch "^\.ht">
    Require all denied
</FilesMatch>

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

IncludeOptional conf-enabled/*.conf    
IncludeOptional sites-enabled/*.conf

ServerName 104.236.87.208    
UseCanonicalName On

Does anyone know what's going on with this?


Update

As requested, here's the contents of my site's .htaccess at the root path:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

Solution

  • I figured out the problem. There were two:

    Problem 1

    mod_cache was running too early in the server processing pipeline. This meant that it cached content before the PHP scripts were called, causing it to cache the directory index instead. To fix this, I turned off CacheQuickHandler in my config file:

    CacheQuickHandler off
    

    Problem 2

    My .htaccess file (automatically generated by WordPress) was rewriting all URIs to /index.php:

    RewriteRule . /index.php [L]
    

    This was causing every page to get cached as index.php, meaning that whenever you visited a page on my website Apache served up whatever the last page visited was.

    Changing it to rewrite URIs to index.php/<the path> fixed this problem:

    RewriteRule ^(.*)$ /index.php/$1 [L]
    

    Thanks to this ServerFault answer for pointing me in the right direction.