Static Cache with public folder setup

I cannot get the staticache plugin to work with my public folder setup. The cache files are generated as expected, but my webserver (Apache) does not seem to be able to pick them up. I know the cache files need to be in my root directory. There are two solutions proposed for this in this Github discussion, but I have tried them both to no avail:

  1. Changed the root for the cache files via the plugin options.
  2. Created a symlink from /public/cache to /storage/cache. The symlink works. I have tried this on two different sites (one on uberspace, on on IONOS) that use symlinks for the media folder so I think this is not the issue. I also tried giving the symlink a different name, like staticache.

I’m currently favoring the second approach. I assume the issue lies with the .htacccesssettings but I cannot figure it out. This is in my /public/.htaccess, but it seems to have no effect:

RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/pages/%{REQUEST_URI}/index.html -f [NC]
RewriteRule ^(.*) %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/pages/%{REQUEST_URI}/index.html [L]

RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/pages/%{REQUEST_URI} -f [NC]
RewriteRule ^(.*) %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/pages/%{REQUEST_URI} [L]

Does anyone have an idea?

in github discussion i read the folder name cache might be reserved. have you tried changing that?

have you verified if the files can be found using the php loader (see example from sciloqi)?

Thanks for getting back!
I did try changing the name of the symlink/cache folder but it had no effect.

The PHP loader does indeed work! Does that give you any hint as to why the server config solution wouldn’t work?

Does setting the RewriteBase to RewriteBase / affect this?

if the php loader works you can now savely assume that the files and symlink are correct and the issue lies somewhere with the apache config. sadly it does not tell us much how to fix that.

personally i would create a few static files manually and try setting the htaccess config for each of them. trying different setup like with or without symlink, different folder names etc. and see which ones are working.

and yes an RewriteBase / affects the 2nd argument of a RewriteRule so maybe you need to remove that.

Thanks a lot, I’ll dig into this and see if I can find a solution. First insight is already that I misunderstood DOCUMENT_ROOT, which apparently always points to Apache’s single DocumentRoot.

For anyone who might stumble upon this thread later. With some great support from the uberspace team I got this to work like this:

The DOCUMENT_ROOT variable is indeed problematic if you have anything other than a standard setup, because it cannot be changed and will lead to wrong paths. The solution is to write the path manually. For my uberspace setup, that looks a little something likes this:

RewriteBase /

RewriteCond /var/www/virtual/jfeige/jonasfeige.com/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI}/index.html -f [NC]
RewriteRule ^(.*) /var/www/virtual/jfeige/jonasfeige.com/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI}/index.html [L]

RewriteCond /var/www/virtual/jfeige/jonasfeige.com/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI} -f [NC]
RewriteRule ^(.*) /var/www/virtual/jfeige/jonasfeige.com/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI} [L]

jonasfeige.com is a symlink that leads to my site’s public folder.
staticache is another symlink within that public folder which leads to /storage/cache.

Hi @jonasfeige,

I’m having similar issue with public folder. Would you mind telling me how you setup your config.php and you symlink in index.php? At the moment I have a symlink for my media folder only in it:


<?php

include '../vendor/autoload.php';

$kirby = new Kirby([
    'roots' => [
        'index'    => __DIR__,
        'base'     => $base    = dirname(__DIR__),
        'site'     => $base . '/site',
        'storage'  => $storage = $base . '/storage',
        'content'  => $storage . '/content',
        'accounts' => $storage . '/accounts',
        'cache'    => $storage . '/cache',
        'logs'     => $storage . '/logs',
        'media'    => $storage . '/media', // NOTE: needs symlink /public/media to /storage/media
        'sessions' => $storage . '/sessions',
    ]
]);
// create symlink if needed
$symlink = __DIR__ . '/media';
if (!file_exists($symlink) && !file_exists($staticache)) {
    symlink($kirby->roots()->media(), $symlink);
}

echo $kirby->render();

Actually I could solved it. So for others you used similar public setup folder I had to do the following:

In my /public/index.php :

<?php

include '../vendor/autoload.php';

$kirby = new Kirby([
    'roots' => [
        'index'    => __DIR__,
        'base'     => $base    = dirname(__DIR__),
        'site'     => $base . '/site',
        'storage'  => $storage = $base . '/storage',
        'content'  => $storage . '/content',
        'accounts' => $storage . '/accounts',
        'cache'    => $storage . '/cache',
        'logs'     => $storage . '/logs',
        'media'    => $storage . '/media', // NOTE: needs symlink /public/media to /storage/media
        'sessions' => $storage . '/sessions',
    ]
]);
// create symlink if needed
$symlink = __DIR__ . '/media';
if (!file_exists($symlink)) :
    symlink($kirby->roots()->media(), $symlink);
endif;
$staticache = __DIR__ . '/staticache';
if(!file_exists($staticache)) :
    symlink($kirby->roots()->cache(), $staticache);
endif;

echo $kirby->render();

In my config.php:

'cache' => [
    'pages' => [
      'active' => true,
      'type'   => 'static',
    ]
]

Finally in the .htaccess:

RewriteCond %{DOCUMENT_ROOT}/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI}/index.html -f
RewriteRule ^(.*) %{DOCUMENT_ROOT}/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI}/index.html [L]

RewriteCond %{DOCUMENT_ROOT}/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI} -f
RewriteRule ^(.*) %{DOCUMENT_ROOT}/staticache/%{SERVER_NAME}/pages/%{REQUEST_URI} [L]

which like Jonas, the “staticache” is a symlink to the original folder which is located outside the public folder, in storage/cache.

Now it works :slight_smile:

1 Like

I think this line in .htaccess file

# block all files in the site folder from being accessed directly
RewriteRule ^site/(.*) index.php [L]

prevents access to the cache files.

I solved it for myself at the moment:

RewriteCond %{REQUEST_URI} !/cache/mydomain.com/pages/
RewriteRule ^site/(.*) index.php [L]

The additional RewriteCond solved the problem.
Unfortunately, I’m not sure whether a security vulnerability has arisen with this.
But maybe someone else has an idea.

Hello,
I would like to ask if anyone has already found a solution or if it works with my solution?

Does nobody have the same problem as me, that the original .htaccess rule described below blocks access to the cache files in the site folder without an additional RewriteCond?

Unfortunately I don’t find anything in the readme.md of the blugin, or have I overlooked that?

My solution is currently to adjust the .htaccess accordingly, as the original rewirte rule of kirby blocks access to the site folder.

# block all files in the site folder from being accessed directly
RewriteCond %{REQUEST_URI} !/cache/(.*)/pages/ 
RewriteRule ^site/(.*) index.php [L]

The plugin is provided by the Kirby team, so I’m asking here in the forum. Should I possibly post this as an issue in GitHub?

I would be very pleased to receive answers.
Robert

personally i am always using the php loader which is only a tiny tinsy bit slower than raw apache but has no issues at all.