Install Apache2 with FastCGI in Ubuntu Server 14.04/13.10

Introduction

In this tutorial, we will install the apache2 with FastCGI. Using Fastcgi with PHP, we can set up multiple PHP version, and use suexec to support web user with their own instance of PHP, which mean we can separate php.ini file for each web users.

Install Apache2

apt-get install apache2 apache2-mpm-worker libapache2-mod-fcgid apache2-suexec-custom

Install PHP5

apt-get install php5 libapache2-mod-php5 php5-cgi php5-cli php5-gd php5-mysql php5-json

Install mysql-client

apt-get install mysql-client

Edit suexec userdir,

vi /etc/apache2/suexec/www-data

with content:

/home/
public_html/cgi-bin

Setting up fcgi in home users.

Create a user name “user1”

useradd -m user1
cd /home/user1

Create folder cgi-bin with a sub directory in home user1.

mkdir -p cgi-bin/php5-default
cd cgi-bin/php5-default

Create a file name php-fcgi-wrapper,

vi php-fcgi-wrapper

with content:

#!/bin/sh
# Wrapper for PHP-fcgi
# This wrapper can be used to define settings before launching the PHP-fcgi binary.
# Define the path to php.ini. This defaults to /etc/phpX/cgi.
export PHPRC=/home/user1/conf
# Define the number of PHP child processes that will be launched.
# This is low to control memory usage on a server that might launch
# these processes for lots of domains.
# Leave undefined to let PHP decide.
export PHP_FCGI_CHILDREN=0
# Maximum requests before a process is stopped and a new one is launched
export PHP_FCGI_MAX_REQUESTS=0

# Launch the PHP CGI binary
# This can be any other version of PHP which is compiled with FCGI support.
exec /usr/bin/php5-cgi

and save and make file executable:

chmod +x php-fcgi-wrapper

create an other folder name conf in this home user1.

mkdir /home/user1/conf
cd /home/user1/conf

Create file php.ini,

vi php.ini

with content:

display_errors = On

Go to home user1 and create folder name public_html.

cd /home/user1
mkdir public_html

Create a phpinfo file in public_html,

cd public_html
vi phpinfo.php

with content:

<?php
phpinfo();
?>

Change ownership to user1.

chown -R user1:user1 /home/user1/

Setting up Virtualhost:

vi /etc/apache2/sites-available/demo1.unixmen.com.conf

with content:

<VirtualHost *:80>
 DocumentRoot /home/user1/public_html
 ServerName demo1.unixmen.com
 SuexecUserGroup user1 user1
 ErrorLog /var/log/apache2/demo1-error_log
 LogLevel debug
 CustomLog /var/log/apache2/demo1-access_log combined
 <Directory />
 Options FollowSymLinks
 AllowOverride All
 Require all granted

</Directory>

AddHandler php-fcgi .php
 Action php-fcgi /fcgi-bin/php-fcgi-wrapper

# FastCgiExternalServer /var/www/cgi-bin/php5-default_php538 -socket /var/run/php5-fpm.sock -pass-header Authorization
 # Define alias "/fcgi-bin/". The action above is using this value, which means that
 # you could run another "php5-cgi" command by just changing this alias

Alias /fcgi-bin/ /home/user1/cgi-bin/php5-default/

# Turn on the fcgid-script handler for all files within the alias "/fcgi-bin/" 
 <Location /fcgi-bin/>
 SetHandler fcgid-script
 Options +ExecCGI
 </Location>
 RewriteEngine On
 RewriteRule ^/fcgi-bin/[^/]*$ / [PT]
</VirtualHost>

Enable site:

a2ensite demo1.unixmen.com.conf

Disable module php5:

a2dismod php5

Enable modules:

a2enmod suexec actions rewrite

Restart service apache2.

service apache2 restart

Check the PHP info for user1.

http://demo1.unixmen.com/phpinfo.php

user1-phpinfo

Setting up fcgi for user2:

Create a user name “user2”

useradd -m user2
 cd /home/user2

Create folder cgi-bin with a sub directory in home user2.

mkdir -p cgi-bin/php5-default
 cd cgi-bin/php5-default
 vi php-fcgi-wrapper

with content:

 #!/bin/sh
 # Wrapper for PHP-fcgi
 # This wrapper can be used to define settings before launching the PHP-fcgi binary.

# Define the path to php.ini. This defaults to /etc/phpX/cgi.
 export PHPRC=/home/user2/conf

# Define the number of PHP child processes that will be launched.
 # This is low to control memory usage on a server that might launch
 # these processes for lots of domains.
 # Leave undefined to let PHP decide.
 export PHP_FCGI_CHILDREN=0

# Maximum requests before a process is stopped and a new one is launched
 export PHP_FCGI_MAX_REQUESTS=0

# Launch the PHP CGI binary
# This can be any other version of PHP which is compiled with FCGI support.
 exec /usr/bin/php5-cgi

and save  and make file executable:

chmod +x php-fcgi-wrapper

create an other folder name conf in this home user1.

mkdir /home/user2/conf
cd /home/user2/conf
vi php.ini

with content:

display_errors = On

Go to home user2 and create folder name public_html.

cd /home/user2
mkdir public_html

Create a phpinfo file in public_html.

cd public_html
vi phpinfo.php

with content:

<?php
phpinfo();
?>

Change ownership to user.

 chown -R user2:user2 /home/user2/

Setting up Virtualhost:

vi /etc/apache2/sites-available/demo2.unixmen.com.conf

with content:

 <VirtualHost *:80>
 DocumentRoot /home/user2/public_html
 ServerName demo2.unixmen.com
 SuexecUserGroup user2 user2
 ErrorLog /var/log/apache2/demo2-error_log
 LogLevel debug
 CustomLog /var/log/apache2/demo2-access_log combined
 <Directory />
 Options FollowSymLinks
 AllowOverride All
 Require all granted

</Directory>

AddHandler php-fcgi .php
 Action php-fcgi /fcgi-bin/php-fcgi-wrapper

# FastCgiExternalServer /var/www/cgi-bin/php5-default_php538 -socket /var/run/php5-fpm.sock -pass-header Authorization
 # Define alias "/fcgi-bin/". The action above is using this value, which means that
 # you could run another "php5-cgi" command by just changing this alias

Alias /fcgi-bin/ /home/user2/cgi-bin/php5-default/

# Turn on the fcgid-script handler for all files within the alias "/fcgi-bin/"
 <Location /fcgi-bin/>
 SetHandler fcgid-script
 Options +ExecCGI
 </Location>
 RewriteEngine On
 RewriteRule ^/fcgi-bin/[^/]*$ / [PT]
 </VirtualHost>

Enable site:

a2ensite demo2.unixmen.com.conf

Restart service apache2

service apache2 restart

Check the PHP info for user2

:http://demo2.unixmen.com/phpinfo.php

user2-phpinfo

Note, Check in these phpinfo for user1 and user2 use different php.ini. We can add specific options for php.ini for each user with different settings. If we do not add for these user php.ini, I will take from the default php.ini.

That’s all, Enjoy 😉