Installing WP Super Cache with lighttpd
19/02/2009Trying to get WP Super Cache & WordPress working on my fast lighttpd server, I came into problems, mainly because of lighttpd’s lack of (Apache’s version of) the mod_rewrite module. The static files that were created from the cache were not statically served from wordpress. The problem is that in order to use them, the PHP fcgi was called for each request. So, why would we have to call PHP every time that a file can be completely statically provided by the web server?
Following this guideI came up with some problems trying to serve the static files. The problem with that version of the rewrite.lua script is that it does not really work the way it should. The whole point of using WP Super Cache is to avoid calling the PHP fcgi for posts that are already cached into an html file. Calling the PHP fcgi is much slower than using the “core” lighttpd static-page-serving facilities.
So, what did I do to avoid calling the PHP fcgi?
The following script takes the url that was asked from the client. It checks whether there is a fresh version of a static HTML page on the cache and if yes, it servers that. If the file does not exist al all or the it is expired(I check its modification date) then the request is forwarded to the PHP fcgi so that it can be freshly served.
In my lighttpd.conf I have put this:
</p><p style="clear: both"> </p><p style="clear: both">$HTTP["host"] == "www.asteriosk.gr" {</p><p style="clear: both"> </p><pre style="clear: both"><code>alias.url = ( "/storage/" => "/opt/storage/" )
server.document-root = "/opt/apps/wordpress/"
url.rewrite = (
"^/(wiki|wp-admin|wp-includes|wp-content|storage)/(.*)" => "$0",
"^/(sitemap.xml|sitemap.xml.gz)" => "$0",
"^/(.*.php)" => "$0",
"^/(.*)$" => "/index.php/$1"
)
magnet.attract-physical-path-to = ( server.document-root + "rewrite.lua" )
</code></pre><p style="clear: both"> </p><p style="clear: both">}
And in the rewrite.lua file I have put this:
expiration_time = 10*60
function serve_html(cached_page, expiration_time)
attr = lighty.stat(cached_page)
--Check if the cached file has expired
if (attr and (attr['st_mtime'] + expiration_time) > os.time() ) then
lighty.env["physical.path"] = cached_page
return true
else
return false
end
end
function serve_gzip(cached_page, expiration_time)
attr = lighty.stat(cached_page .. ".gz")
--Check if the gziped cached file has expired
if (attr and (attr['st_mtime'] + expiration_time) > os.time() ) then
lighty.header["Content-Encoding"] = "gzip"
lighty.header["Content-Type"] = ""
lighty.env["physical.path"] = cached_page .. ".gz"
return true
else
return false
end
end
attr = lighty.stat(lighty.env["physical.path"])
if (not attr) then
lighty.env["physical.rel-path"] = lighty.env["uri.path"]
--Change the "/opt/apps/wordpress/" to your own wordpress location
lighty.env["physical.path"] = "/opt/apps/wordpress/"
.. lighty.env["physical.rel-path"]
-- If we are querying, we don't have to cache of course
query_condition = not ( lighty.env["uri.query"] and
string.find(lighty.env["uri.query"], ".*s=.*"))
--If there exists a cookie in the client, probably he/she has been here before
--and has left a comment. In that case we don't use cached content
--for example, the user might has just submitted a comment.
user_cookie = lighty.request["Cookie"] or "no_cookie_here"
cookie_condition = not (string.find(user_cookie, ".*comment_author.*") or
string.find(user_cookie, ".*wordpress.*") or
string.find(user_cookie, ".*wp-postpass_.*"))
if (query_condition and cookie_condition) then
--construct the full path of the expeted cached filename for this url
accept_encoding = lighty.request["Accept-Encoding"] or "no_acceptance"
cached_page = lighty.env["physical.doc-root"] ..
"/wp-content/cache/supercache/" ..
lighty.request["Host"] ..
lighty.env["request.uri"] ..
"/index.html"
cached_page = string.gsub(cached_page, "index.php/", "/")
cached_page = string.gsub(cached_page, "//", "/")
--If the client accepts gzipped content, send gzipped content
if (string.find(accept_encoding, "gzip")) then
--If for some reason the gzipped file does not exist, fallback to the
--uncompressed cached file
if not serve_gzip(cached_page, expiration_time) then
serve_html(cached_page,expiration_time) end
else
serve_html(cached_page,expiration_time)
end
end
end
If you want to use the script in your own server, the only things that you have to change is the hardcoded /opt/apps/wordpress/ path and the expiration_time variable.
Kudos to Giovanni Intini for porting the Apache modrewrite’s rules on modmagnet and the original idea of the script.
There are 20 comments in this article: