Putting a limit on Apache and PHP memory usage

A little while ago, we ran into memory problems on mahara.org. It turned out to be due to the GD library having issues with large (as in height and width, not file size) images.

What we discovered is that the PHP memory limit (which is set to a fairly low value) only applies to actual PHP code, not C libraries like GD that are called from PHP. It's not obvious what PHP libraries are implemented as external C calls, which fall outside of the control of the interpreter, but anything that sounds like it's using some other library is probably not in PHP and is worth looking at.

To put a cap on the memory usage of Apache, we set process limits for the main Apache process and all of its children using ulimit.

Unfortunately, the limit we really wanted to change (resident memory or "-m") isn't implemented in the Linux kernel. So what we settled on was to limit the total virtual memory that an Apache process (or sub-process) can consume using "ulimit -v".

On a Debian box, this can be done by adding this to the bottom of /etc/default/apache2:

ulimit -v 1048576

for a limit of 1GB of virtual memory.

You can ensure that it works by setting it first to a very low value and then loading one of your PHP pages and seeing it die with some kind of malloc error.

I'm curious to know what other people do to prevent runaway Apache processes.

Watching Gerrit merges on IRC using cia.vc

In order to get a notice on IRC whenever someone merges a change in Mahara, we picked the cia.vc service. This allows us to keep an eye on what is happening with the codebase.

If you want to replicate our setup, start by creating an account on cia.vc and then add a new project and an IRC bot to your account.

Registering an IRC channel for the commits

To avoid interrupting our main developer channel with commit messages, I thought of creating a separate channel for it on Freenode:

/msg chanserv register #mahara-commits  
/msg chanserv op #mahara-commits fmarier  
/msg chanserv set #mahara-commits guard on  
/msg chanserv set #mahara-commits topiclock on  
/msg chanserv set #mahara-commits email dev@mahara.org  
/msg chanserv set #mahara-commits url https://gitorious.org/mahara/mahara/commits  
/msg chanserv set #mahara-commits secure on  
/msg chanserv set #mahara-commits keeptopic on  
/msg chanserv topic #mahara-commits Mahara project | https://mahara.org | Commit log from http://cia.vc/stats/project/Mahara

Sending code updates to cia.vc

Since the place where we host our code, Gitorious, doesn't support automatic notifications to cia.vc, we added a merge hook into our code review system to let cia.vc know whenever a commit gets merged into our branch.

You can take a look at the custom hook script we wrote for this (note that this script also updates our bugtracker at the same time), but here are a few notes if you want to write your own cia.vc client script:

  • Client scripts can submit data via email or XMLRPC.
  • The data needs to be sent in an XML document.
  • Make sure your text nodes are trimmed and avoid CDATA sections.
  • Keep an eye on Freenode's #commits while testing your script.