Twig cache permissions for Apache + cron on CentOS

I probably should have seen this coming, but when introducing Twig to a non-Symfony project, it hadn’t occurred to me to expect the same permissions dance that Symfony cover helpfully in their setup guide.

Having built a shiny new system that uses the same template cache for web requests (handled by the Apache user) and emailed reports (handled by another user via cron / command-line invocation), of course I hit exactly the same problem that those steps avoid. If you share any templates across the two users’ remits, eventually one will want to write to an existing cache file generated by the other user. It won’t have write permission, and Twig will freak out:

Uncaught exception ‘RuntimeException’ with message ‘Unable to write in the cache directory (…/cache/twig/…).’ in …/vendor/twig/twig/lib/Twig/Environment.php:1239

One approach to get around this is to change Twig’s behaviour in handling the files. I found a nice post here describing a process which I expect would also have worked, which involves extending Twig_Environment. However as this is an issue specific to where I’m deploying, I was hoping for a filesystem-level fix – preferably not something which required overriding Twig’s behaviour or creating a separate cache for each user.

Maybe this should be common sense but it took me a few minutes to work out. I had a system running CentOS, configured via cPanel in the days before I was slightly braver with sysadmin Linux-y things. For some reason the standard config comes with root SSH access and no sudo. And the OS had no chmod +a support or ACLs enabled.

So my complete steps to get this working – where MYUSER is my CLI  task invoking user – were:

  • SSH in as root – or (preferably) don’t and use sudo for all the below
  • yum install acl – if you’re on a Redhat-based Linux flavour like CentOS
  • cp /etc/fstab /etc/fstab.bak
  • nano /etc/fstab
  • Add ,acl to the options for the main partition (e.g. /) and save (Ctrl + O, [return], Ctrl + X)
  • mount -o remount / (assuming the partition is at /) to make ACL support kick in
  • cd to just above your cache directory – let’s assume it’s called cache
  • Then we can just borrow all the clever bits from Symfony’s guide:
    • rm -rf cache
    • mkdir cache
    • HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\  -f1`
    • setfacl -R -m u:"$HTTPDUSER":rwX -m u:MYUSER:rwX cache
    • setfacl -dR -m u:"$HTTPDUSER":rwX -m u:MYUSER:rwX cache

Done! The server now speaks ACL, and Twig should play happily with both PHP users.

Leave a Reply

Your email address will not be published. Required fields are marked *