Freelance Projects

Upeksha Wisidagama

Apache2 FastCGI and suEXEC Implementing APC Per User With PHP5-CGI

Each user can be given their own Alternative PHP Cache (APC) with PHP running as a seperate process. First we need to disable Apache2 PHP module which is enabled by default. After doing this you no longer can set PHP settings in .htaccess files. Apache2 will have no knowledge about PHP, it only passes the execution to a seperate PHP process via FastCGI module.

Setting up a local Ubuntu Server is recommended to read before this post to learn how to setup a local Ubuntu Server.

Disable Apache2 PHP5 Module and Install PHP CGIs

Note the highlighted Resident and Shared memory consumption by Apache2 parent process and its children.

Apache2 Prefork with Mod_PHP

Disable mod_php with sudo a2dismod php5. Restart web server with sudo service apache2 restart. Now, if you check your ‘/etc/apache2/mods-enabled’ directory, you will notice that php.conf and php5.load files have been deleted.

Apache2 Prefork without Mod_PHP

Again, note the reduction of the memory consumption by Apache.

Next, you need to install php5-cgi. Run sudo apt-get install php5-cgi. After installation you will have two new executables (php-cgi and php5-cgi) in /usr/bin/ directory.

Install and Enable Apache2 FastCGI Module

Run sudo apt-cache search apache2 cgi and find the relevant module. Install using sudo apt-get install libapache2-mod-fastcgi. Restart the server once again. If you check /etc/apache2/mods-enabled directory, you will see FastCGI is enabled automatically after installation.

Add the FastCGI configuration to the apache2.conf file in /etc/apache2 directory.

‘FastCGI Configuration (/etc/apache2/apache2.conf)’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# FastCGI
<IfModule mod_fastcgi.c>

FastCgiConfig -idle-timeout 20 -maxClassProcesses 1
FastCgiWrapper on

AddHandler php5-fcgi .php
Action php5-fcgi /cgi-bin/php-fastcgi

<Location "/cgi-bin/php-fastcgi">
  Order Deny,Allow
  Deny from All
  Allow from env=REDIRECT_STATUS
  Options ExecCGI
  SetHandler fastcgi-script
</Location>
</IfModule>

You might need to enable Action command via sudo a2enmod actions to parse the above configuration.

Install and Enable Apache2 suEXEC

sudo apt-get install apache2-suexec

Enable ‘suEXEC’ with sudo a2enmod suexec.

Create PHP FastCGI wrapper scripts in /var/www/bin/ directory. Create a new directory for ‘wisidagama’. Create the ‘php-fastcgi’ wrapper script.

‘Fast CGI PHP Wrapper (/var/www/bin/wisidagama/php-fastcgi)’
1
2
3
4
5
6
7
8
9
#!/bin/sh

PHP_FCGI_CHILDREN=2
export PHP_FCGI_CHILDREN
PHP_FCGI_MAX_REQUESTS=500
export PHP_FCGI_MAX_REQUESTS

umask 0022
exec /usr/bin/php5-cgi -d apc.shm_size=50M

Be sure to read and understand the suEXEC Security Model too.

Install and Enable PHP APC

sudo apt-get install php-apc

You should get an apc.ini file in /etc/php5/cgi/conf.d directory. Enter apc.enabled="1" to enable APC for CGI PHP.

Add a User and Create a simple website

Add a new user called ‘wisidagama’. sudo useradd wisidagama.

‘Creating a New User’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
upeksha@uwlab:/home$ sudo useradd -d /home/wisidagama -m wisidagama
upeksha@uwlab:/home$ sudo passwd wisidagama
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
upeksha@uwlab:/home$ ls
upeksha  wisidagama
upeksha@uwlab:/home$ ls -al
total 16
drwxr-xr-x  4 root       root       4096 Jul  8 00:34 .
drwxr-xr-x 22 root       root       4096 Jul  7 10:52 ..
drwxr-xr-x  4 upeksha    upeksha    4096 Jul  7 23:41 upeksha
drwxr-xr-x  2 wisidagama wisidagama 4096 Jul  8 00:34 wisidagama
upeksha@uwlab:/home$

Let’s create a simple two-page website for wisidagama.

‘Creating a Simple Site’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
upeksha@uw:~/test$ ssh wisidagama@uwlab
wisidagama@uwlab's password:
Welcome to Ubuntu 12.04.2 LTS (GNU/Linux 3.5.0-23-generic i686)
...
$ ls -al
total 28
drwxr-xr-x 3 wisidagama wisidagama 4096 Jul  8 00:45 .
drwxr-xr-x 4 root       root       4096 Jul  8 00:34 ..
-rw-r--r-- 1 wisidagama wisidagama  220 Apr  3  2012 .bash_logout
-rw-r--r-- 1 wisidagama wisidagama 3486 Apr  3  2012 .bashrc
drwx------ 2 wisidagama wisidagama 4096 Jul  8 00:45 .cache
-rw-r--r-- 1 wisidagama wisidagama  675 Apr  3  2012 .profile
-rw------- 1 wisidagama wisidagama  594 Jul  8 00:44 .viminfo
$ mkdir public_html
$ cd public_html
$ vi phpinfo.php
$ vi index.php
$ ls -al
total 16
drwxrwxr-x 2 wisidagama wisidagama 4096 Jul  8 00:47 .
drwxr-xr-x 4 wisidagama wisidagama 4096 Jul  8 00:47 ..
-rw-rw-r-- 1 wisidagama wisidagama   29 Jul  8 00:47 index.php
-rw-rw-r-- 1 wisidagama wisidagama   20 Jul  8 00:47 phpinfo.php

Next we need serve these files as www.wisidagama.dev. Setup a Virtual Host for wisidagama.dev.

Copy the ‘default’ file to ‘wisidagama.dev’ in ‘/etc/apache2/sites-available’ directory. Edit the file as follows.

‘wisidagama.dev’
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<VirtualHost *:80>
  ServerName www.wisidagama.dev
  ServerAdmin webmaster@wisidagama.dev

  DocumentRoot /home/wisidagama/public_html/
  <Directory /home/wisidagama/public_html/>
      Options Indexes FollowSymLinks MultiViews
      AllowOverride None
      Order allow,deny
      allow from all
  </Directory>

  <IfModule mod_fastcgi.c>
        SuexecUserGroup wisidagama wisidagama
        Alias /cgi-bin/ /var/www/bin/wisidagama/
    </IfModule>

  ErrorLog /home/wisidagama/error.log

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel warn

  CustomLog /home/wisidagama/access.log combined
</VirtualHost>

Enable wisidagama.dev using sudo a2ensite wisidagama.dev.

From the client machine we need to tell www.wisidagama.dev to resolve to 192.168.1.8 since we don’t have a DNS server to resolve this. Add the following line to your /etc/hosts file.

192.168.1.8 www.wisidagama.dev

Disabling FastCGI or suEXEC

If you disable FastCGI module using sudo a2dismod fastcgi, then no one will handle .php files (Remember: AddHandler php5-fcgi .php). They will be downloaded to client machines.

If you disable suExec module using sudo a2dismod suexec, Apache will fail.

‘Apache2 Fails to Start (/var/log/apache2/error.log)’
1
2
3
4
5
6
upeksha@uwlab:~$ sudo service apache2 restart
Syntax error on line 14 of /etc/apache2/sites-enabled/wisidagama.dev:
Invalid command 'SuexecUserGroup', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.
The Apache error log may have more information.
   ...fail!

Configuring APC size Per User

You can fine tune per user APC size in ‘/var/www/bin/USER/php-fastcgi scripts. Use the -d apc.shm_size=100M argument to adjust per user APC size. See below, phpinfo() output shows the custom APC size for ‘wisidagama’.

CGI-FastCGI as PHP Sever API

APC configuration:

PHP FastCGI APC Enabled

APC size per user:

PHP APC SHM Size

Resource Consumption of PHP CGI running via FastCGI and usEXEC with per user APC

PHP CGI Process Resource Consumption

Now you can fine tune the various parameters to match your server needs and wants. Note: Apache2 still uses Prefork MPM.

PHP as CGI process with Apache2 Prefork MPM