Installing WP Super Cache with lighttpd


Trying 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"] == "" {</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
    return false

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
    return false

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"] .. 

    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

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 35 comments in this article:

  1. 3/07/2009marty baratz say:

    Great work

  2. 3/07/2009rodrigo duran say:

    thank you dear friend,

  3. 3/07/2009KATHY COMER say:

    Hi can someone please translate for me thanx,

  4. 3/07/2009Aaron Bremer say:

    Thanks this design is very good..,

  5. 3/07/2009tai truong say:

    Good One!,

  6. 1/08/2009Lighttpd and WP Super Cache « The Zash Blag say:

    […] would you need lua scripting to serve cached static files when you can symlink everything in wp-content/cache/supercache/*blog.hostname*/ to the wordpress […]

  7. 2/08/2009PHP Trivandrum » Wordpress Super Cache on lighttpd say:

    […] Read the rest of his version Installing WP Super Cache with lighttpd […]

  8. 24/08/2009Wordpress Lighttpd vs. Apache Httpd Perfomance Test « Web Server Hacks Blog – Hacks for Dedicated/VPS Servers, SSH, and Plesk say:

    […] with Mod_Rewrite and Mod_Magnet based on method.  This method supposedly improves upon the method  below but I did not notice any […]

  9. 28/09/2009chris say:

    quick q: why do you set the content-type to be blank?

  10. 29/09/2009Asterios Katsifodimos say:

    Hi Chris,

    The content-type=”” does not need to be blank as I see here:

    I suppose that the best would be to set like this:
    lighty.header[“Content-Type”] = “text/html”

    Good point!

  11. 7/10/2009Joop say:

    YES! Thank you, this worked for me…

  12. 13/11/2009gomobi say:

    I think you can use Hyper Cache under Lighttpd without extra configuation

  13. 13/11/2009Asterios Katsifodimos say:

    Yes you can, but you don’t avoid the PHP subsystem calls. This way, you bypass the PHP subsystem completely! If you need a straight drop-in cache, you can go for Hyper Cache, it will not make much difference in a low-visit site.

  14. 8/01/2010tk say:


    it did not work out for me, perhaps this is a lighty 1.4 VS 1.5 issue.. anyhow, the above lua would never cache the index here is my solution: (including some other performance tweaks)

  15. 17/01/2010wrongy say:

    Your lighttpd.conf code is wrong because the HTML code written into the real code.

  16. 2/04/2010how to get fat thigs say:

    hey! this is the perfect example of a good wordpress template right? seems all so organized that makes me think its more than perfect! fine posts btw, waiting for more!

  17. 17/06/2010tiefiamiMeN say:

    You content is great.
    Recent elections have seen miss world?

    look this:

  18. 6/02/2011WP Super Cache + Lighttpd » ab, apache2-utils, Lighttpd, optimierung, Wordpress, WP Super Cache » Peter Pen say:

    […] Du installierst lighttpd-mod-magnet, legst die Datei /etc/lighttpd/wpsupercache.lua und fügst diesen Code, bearbeitet ein. und jetzt nur noch das Modul mod_magnet laden, die Datei einbinden und schon […]

  19. 10/02/2011WP Super Cache + Lighttpd - Peter Pen say:

    […] ;)Du installierst lighttpd-mod-magnet, legst die Datei /etc/lighttpd/wpsupercache.lua und fügst diesen Code, bearbeitet ein.und jetzt nur noch das Modul mod_magnet laden, die Datei einbinden und schon […]

  20. 4/09/2011Virtual Private SEnuke X Servers (VPS) say:

    I’m having trouble trying to understand exactly what is a Virtual Private Server (aka VPS).. . What are some of its uses and why would a person need one? Thanks in advance :-).

  21. 24/02/2012Adriana say:

    thanks for share!

  22. 5/03/2012ELITE BOHEMIA say:

    Buen reportaje, soy visitante habitual de, mantener el funcionamiento agradable, y que va a ser un visitante regular durante mucho tiempo.

  23. 8/04/2013Arts say:

    It’s awesome to go to see this web site and reading the views of all friends concerning this paragraph, while I am also eager of getting knowledge.

  24. 23/06/2013how to Become a certified orthotist say:

    Hey there! This is my 1st comment here so I just
    wanted to give a quick shout out and tell you I really enjoy
    reading your blog posts. Can you suggest any other blogs/websites/forums that deal with the same topics?
    Many thanks!

  25. 5/07/2013buy senuke xcr vps say:

    Asking questions are really good thing if you are
    not understanding anything fully, except this post offers fastidious understanding yet.

  26. 5/07/20135 social networking safety tips say:

    Malicious users can gather this information and literally use
    this information for their personal gain. We need to have
    interaction with other and to make it happen we arrange parties and make visits to
    others to stay in touch with them. Although interest or opinions may vary from group to group there still remains a common interest in national or world news.

  27. 11/07/2013organic food restaurants say:

    Hey there! I realize this is somewhat off-topic but I had to
    ask. Does operating a well-established blog like yours require a lot
    of work? I’m brand new to running a blog however I do write in my journal every day. I’d like
    to start a blog so I can easily share my experience and feelings online.

    Please let me know if you have any kind of recommendations
    or tips for new aspiring bloggers. Appreciate it!

  28. 22/08/2013cost-free information. say:

    People everywhere ‘ regardless of their phone type ‘ have needs for communication and entertainment.

    In this game, your fingers slide over the screen to tilt, slide, jump, and turn through
    the blockades and courses that are as difficult as they are addicting.
    But once connected, you can transfer files to and from your phone (wirelessly) and much more.

  29. 12/03/2014submit articles say:

    Spot on with this write-up, I absolutely think this web site needs a great deal more
    attention. I’ll probably be returning to see more, thanks for the

  30. 14/07/2014packers and mover delhi say:

    You actually make it seem so easy with your presentation but I find this matter to be
    actually something that I think I would never understand.
    It seems too complicated and extremely broad for me.
    I am looking forward for your next post, I’ll try to get the hang of it!

  31. 15/08/2014shaving once say:

    Helko to all, how is all, I think every one is getting more from this web site,
    annd your views are pleasant in suppor of new

  32. 16/09/2014Sylvester say:

    Hmm it appears like your blog ate my first comment (it was super long)
    so I guess I’ll just sum it up what I submitte and
    say, I’mthoroughly enjoying your blog. I too am an aspiring blog writer but I’m still
    new to everything. Do you have any recommendations for first-time blog writers?
    I’d realy appreciate it.

  33. 8/11/ say:

    Due to popularity, it was adopted into its own game. In fact, their
    behavior is likely to get even worse because they no longer have to
    worry about their account getting banned. Check out image
    ten in the slide show (warning: profane language)
    where a player calls his teammates noobs and drops multiple F-bombs.

  34. 26/03/2015droger kopen say:

    Nice response in return oof this question with firm argumentss and
    explaining all on the topic of that.

  35. 10/06/2015Melvincimb say:

    I have been student and i learned that i need something like this!

    this link

Write a comment: