Setup A Website


  • You must read and follow previous instructions on creating a Website User.

Create Basic Virtual Host Record

Each website has it's own virtual host file which needs to be located in the /etc/apache2/sites-available/ directory. In this example we'll create a name-based virtual hosted site, "".

First create (/etc/apache2/sites-available/ so that it resembles the following:

<VirtualHost *:80>
DocumentRoot /www/mysite/public_html

<Directory /www/mysite/public_html>
    Options +FollowSymLinks -SymLinksIfOwnerMatch
    allow from all
    AllowOverride All


Add PHP Support

If you plan to add PHP scripting to a website then we need to do two things:

Create a Wrapper Script

The Apache suEXEC security model requires that the CGI binary meet some pretty stringent requirements concerning file ownership and permissions. Rather than copying the php-cgi binary for each user, we create multiple wrapper scripts around the php-cgi binary. These wrapper scripts allow us to set options on a per-user/website basis.

I keep my wrapper scripts in /var/www/bin, though you may keep yours wherever you want. Each user has a directory in /var/www/bin, for example:

$ ls -l /var/www/bin
dr-xr-xr-x 2 mysite mysite 104 Jun 24 13:56 mysite/
dr-xr-xr-x 2 snakeoil snakeoil 104 Jun 24 13:56 snakeoil/

Inside each user’s bin directory is a single wrapper script, php-fastcgi:

$ ls -l /var/www/bin/mysite/
-r-xr-x‐‐‐ 1 bob bob 145 Jun 24 13:56 php-fastcgi

I’ve shown the ls -l output to show the file and directory ownership and permissions. These are important, and Apache suEXEC will not work correctly if the owner and permissions are not correct.

The contents of the php-fastcgi file in each user’s bin directory (see below for an explanation):



umask 0022
exec /usr/bin/php-cgi -d apc.shm_size=25

This variable tells PHP how many child processes it should spawn. As we discussed earlier, our PHP process will act as “process manager” and pass incoming requests to its children. The parent will maintain a single opcode cache which each child will share. The PHP_FCGI_CHILDREN variable tells PHP how many children to spawn. Another way to think of this is the number of concurrent PHP requests that can be handled per user.

PHP is known for memory leaks in long running processes. This variable causes each child process to be restarted once it has served a given number of requests (e.g. 500). Only the child process is restarted, the parent process remains. Since the parent process maintains the opcode cache, the opcode cache persists.

umask 0022
This sets the umask the PHP binary will run under. Some people may prefer a stricter umask such as 0077, however I’ve found 0022 works best as it allows the Apache server running as nobody to read static files written earlier by a suEXEC’d PHP process. Some PHP applications (WordPress plugins) do not do a good job with permissions, and a strict umask can cause applications to fail.

exec /usr/bin/php-cgi -d apc.shm_size=25
This line calls the php-cgi binary and modifies the APC cache size. It is possible to configure this to use a separate php.ini file instead of setting configuration parameters on the command line, however I like the ability to share a single php.ini file.

Amend The Virtual Host Record

On my host, every virtual host is associated with one user. And every user has exactly one opcode cache. A single user can have multiple virtual hosts (websites), but these virtual hosts share the same opcode cache.

For each virtual host, I add the following lines, customized for the user associated with that virtual host (in this example it's user mysite):

<VirtualHost *:80>
<IfModule mod_fastcgi.c>
   SuexecUserGroup mysite mysite
   Alias /cgi-bin/ /var/www/bin/mysite/

In addition we need to add the +ExecCGI flag to the Options directive so that the site is allowed to execute CGIs:

Options +ExecCGI +FollowSymLinks -SymLinksIfOwnerMatch

When combined with the global apache settings and the wrapper scripts, this will launch the php-cgi binary using suEXEC to execute as the appropriate user and group whenever a .php file is requested.

There are several different ways to call the FastCGI binary. On my hosts, users don’t have access to their cgi-bin directory. The /var/www/bin directory is not accessible by ordinary users. This doesn’t have to be the case, the cgi-bin directory could be stored in the user’s directory. It is important to note that allowing the user to modify php.ini values allows them to modify their opcode cache size, which could have severe repercussions on RAM usage.

Enable/Disable A Site

To enable a website issue the following command:

sudo a2ensite

where the is the same as the previously created virtual host file found under /etc/apache2/sites-available/

Likewise, to disable a site, use the command:

sudo a2dissite

Finally, restart the Apache server to initialize all the changes, with this command:

sudo /etc/init.d/apache2 restart

In the future when you create or edit any virtual host file you'll need to reload the config, which you can do without restarting the server with the following command:

sudo /etc/init.d/apache2 reload
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License