ผมแกะๆ mod_fcgi บน Ubuntu 8.10 แล้วก็เข้าท่าดีครับ เหมาะสำหรับการใช้ PHP ในสิทธิ์ของผู้ใช้แทนที่จะใช้สิทธิ์ของ Apapche ซึ่งการ config ก็ไม่ได้ยุ่งยากมากนัก อีกทั้งยังสะดวกในการทำ Virtual Host อีกด้วย ลองมาดูวิธีการกันครับ อ้อก่อนจะลงมือทำมาดู config ของผมกันก่อน ผมใช้ชื่อเครื่องว่า server1.example.com มี IP address เป็น 192.168.0.100 และเราจะสร้าง Apache vhost ชื่อ www.example1.com และ www.example2.com เพื่อใช้ทดสอบ mod_fcgid เอาล่ะมาเริ่มกันเลย
ขั้นแรกแปลงร่างเป็น root กันก่อนเพื่อความคล่องตัว ใช้คำสั่ง
sudo su
จากนั้นสร้าง symbolic link ให้ /bin/sh เป็น /bin/dash เราจะใช้ bash กันครับ
ln -sf /bin/bash /bin/sh
ถ้าเปิดใช้ AppArmor อยู่ก้อให้ถอดออกก่อน ใช้คำสั่ง
/etc/init.d/apparmor stop
update-rc.d -f apparmor remove
apt-get remove apparmor apparmor-utils
ติดตั้ง Apache/mod_fcgi/PHP5 โดยใช้คำสั่ง
apt-get install apache2 apache2-suexec libapache2-mod-fcgid php5-cgi
ถ้าติดตั้ง Apache2 และ PHP5 อยู่ก่อนแล้วให้ disable โมดูล PHP5 ก่อนด้วยคำสั่ง
a2dismod php5
จากนั้น enable โมดูลที่ต้องใช้ดังนี้
a2enmod rewrite
a2enmod suexec
a2enmod include
a2enmod fcgid
จากนั้นแก้ไขไฟล์ php.ini
vi /etc/php5/cgi/php.ini
เพิ่ม cgi.fix_pathinfo = 1 ตรงท้ายไฟล์
จากนัน reload Apache2 ด้วยคำสั่ง
/etc/init.d/apache2 force-reload
ตอนนี้เราจะได้ Apache2, mod_fcgi และ PHP5 แล้ว
ทีนี้มาสร้าง vhost เพื่อทดสอบกันครับ ถ้ายังจำกันได้เราจะสร้าง vhost 2 อันได้แก่ www.example1.com และ www.example2.com ใน /var/www/web1/web และ /var/www/web2/web ตามลำดับ ตั้งค่า owner และ group ให้ตรงตามผู้ใช้และกลุ่ม คือ web1 และ web2 สร้าง user และ group
groupadd web1
groupadd web2
useradd -s /bin/false -d /var/www/web1 -m -g web1 web1
useradd -s /bin/false -d /var/www/web2 -m -g web2 web2
จากนั้นสร้าง document root ให้แต่ละ vhost พร้อมกำหนดกลุ่มและผู้ใช้ดังนี้
mkdir -p /var/www/web1/web
chown web1:web1 /var/www/web1/web
mkdir -p /var/www/web2/web
chown web2:web2 /var/www/web2/web
เราจะใช้ PHP โดยใช้ suExec โดยระบุ document root เป็น /var/www โดยใช้คำสั่ง
/usr/lib/apache2/suexec -V
เมื่อใช้คำสั่งนี้แล้วเราจะไม่สามารถใช้ PHP ใน /usr/lib/cgi-bin/php ได้เพราะอยู่นอก document root ของ suExec แต่มีทางแก้ไขได้คือ สร้าง symlink ของ /usr/lib/cgi-bin/php มาไว้ใน document root แทน เอ้าสร้าง /var/www/php-fcgi-scripts/web1 และ /var/www/php-fcgi-scripts/web2 เพื่อเป็นจุดวางกันก่อน
mkdir -p /var/www/php-fcgi-scripts/web1
mkdir -p /var/www/php-fcgi-scripts/web2
สร้าง php-fcgi-starter เพื่อเป็น config กำหนดการใช้งาน ในแต่ละ vhost ตัวแรกดังนี้
vi /var/www/php-fcgi-scripts/web1/php-fcgi-starter
ใส่ข้อมูลลงไปดังนี้
#!/bin/sh
PHPRC=/etc/php5/cgi/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/lib/cgi-bin/php
สร้าง php-fcgi-starter เพื่อเป็น config กำหนดการใช้งาน ในแต่ละ vhost ตัวที่สองดังนี้
vi /var/www/php-fcgi-scripts/web2/php-fcgi-starter
ใส่ข้อมูลลงไปดังนี้
#!/bin/sh
PHPRC=/etc/php5/cgi/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/lib/cgi-bin/php
เอาล่ะเปลี่ยนสิทธิ์ให้ php-fcgi-starter ของเรา execute ได้ และกำหนดผู้ใช้และกลุ่มให้ถูกต้อง
chmod 755 /var/www/php-fcgi-scripts/web1/php-fcgi-starter
chmod 755 /var/www/php-fcgi-scripts/web2/php-fcgi-starter
chown -R web1:web1 /var/www/php-fcgi-scripts/web1
chown -R web2:web2 /var/www/php-fcgi-scripts/web2
จากนั้นสร้าง Apache vhost สำหรับ www.example1.com และ www.example2.com สร้าง vhost config ลงใน /etc/apache2/sites-available/ ดังนี้
vi /etc/apache2/sites-available/web1
ใส่ข้อมูล web1 ดังนี้
<VirtualHost *:80>
ServerName www.example1.com
ServerAlias example1.com
ServerAdmin webmaster@example1.com
DocumentRoot /var/www/web1/web/
<IfModule mod_fcgid.c>
SuexecUserGroup web1 web1
PHP_Fix_Pathinfo_Enable 1
<Directory /var/www/web1/web/>
Options +ExecCGI
AllowOverride All
AddHandler fcgid-script .php
FCGIWrapper /var/www/php-fcgi-scripts/web1/php-fcgi-starter .php
Order allow,deny
Allow from all
</Directory>
</IfModule>
# ErrorLog /var/log/apache2/error.log
# CustomLog /var/log/apache2/access.log combined
ServerSignature Off
</VirtualHost>
สั่งให้ vhost web1 ทำงานโดยใช้คำสั่ง
a2ensite web1
จากนั้นสร้าง vhost ของ web2 ดังนี้
vi /etc/apache2/sites-available/web1
ใส่ข้อมูล web ดังนี้
<VirtualHost *:80>
ServerName www.example2.com
ServerAlias example2.com
ServerAdmin webmaster@example2.com
DocumentRoot /var/www/web2/web/
<IfModule mod_fcgid.c>
SuexecUserGroup web2 web2
PHP_Fix_Pathinfo_Enable 1
<Directory /var/www/web2/web/>
Options +ExecCGI
AllowOverride All
AddHandler fcgid-script .php
FCGIWrapper /var/www/php-fcgi-scripts/web2/php-fcgi-starter .php
Order allow,deny
Allow from all
</Directory>
</IfModule>
# ErrorLog /var/log/apache2/error.log
# CustomLog /var/log/apache2/access.log combined
ServerSignature Off
</VirtualHost>
สั่งให้ vhost web2 ทำงานโดยใช้คำสั่ง
a2ensite web2
จากนั้น reload Apache2 ได้เลย โดยใช้คำสั่ง
/etc/init.d/apache2 reload
มาทดสอบกัน เขียนไฟล์ phpinfo ลงใน vhost ทั้ง 2 อัน
vi /var/www/web1/web/info.php
ใส่ข้อมูลดังนี้
<?php
phpinfo();
?>
ลองเปิด browser แล้ว browse ไปที่ http://www.example1.com/info.php
ถ้ามีผลลัพท์ของ PHP Info มาถูกต้อง ก็ถือว่าเป็นอันใช้ได้ครับ อ้อลืมไปเราสามารถกำหนดที่อยู่ของ php.ini ได้เพราะเราสร้าง php-fcgi-starter เอาไว้แล้ว ให้แก้ไขไฟล์นี้เพื่อกำหนดที่อยู่ใหม่ของ php.ini กันครับ ทดลองกับ vhost web2 ครับ ดังนั้นเราจะเอา php.ini เอาไว้ที่ /var/www/web2/ ของ web2 กันครับ
คัดลอกและเปลี่ยนสิทธิ์ ของไฟล์ให้ถูกต้อง
cp /etc/php5/cgi/php.ini /var/www/web2/
chown web2:web2 /var/www/web2/php.ini
แก้ไขไฟล์ /var/www/php-fcgi-scripts/web2/php-fcgi-starter กันครับ
vi /var/www/php-fcgi-scripts/web2/php-fcgi-starter
ดูตรง PHPRC กำหนดที่อยู่ให้ php.ini ใหม่ดังนี้
#!/bin/sh
PHPRC=/var/www/web2/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/lib/cgi-bin/php
จากนั้น reload Apache2 ด้วยคำสั่ง
/etc/init.d/apache2 reload
สร้างไฟล์ phpinfo เพื่อทดสอบ
vi /var/www/web2/web/info.php
ใส่ข้อมูลดังนี้
<?php
phpinfo();
?>
เปิด browser แล้ว browse ไปที่ http://www.example2.com/info.php สังเกตตรง Loaded Configuration File จะเป็น /var/www/web2/php.ini
สำหรับการกำหนดค่า config ใ้ห้ PHP สามารถกำหนดได้ 2 ที่คือ php.ini หรือใช้ wrapper script คือ php-fcgi-starter ได้เช่นกัน ตัวอย่างเช่นเราจะกำหนดให้ magic_quotes_gpc เป็น off เราสามารถเพิ่ม script ลงในไฟล์ /var/www/php-fcgi-scripts/web2/php-fcgi-starter ได้ดังนี้
vi /var/www/php-fcgi-scripts/web2/php-fcgi-starter
เพิ่มข้อมูลดังนี้
#!/bin/sh
PHPRC=/etc/php5/cgi/
export PHPRC
export PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_CHILDREN=8
exec /usr/lib/cgi-bin/php -d magic_quotes_gpc=off
เปิด browser แล้ว browse ไปที่ http://www.example2.com/info.php ครับแล้วจะพบว่า magic_quotes_gpc เปลี่ยนเป็น off แล้ว
การใช้ fcgi เหมาะกับการทำ vhost ที่ต้องการตั้งค่า config ของ PHP เองโดยที่ไม่ต้องอิงค่าของ host ทำให้บริการจัดการทรัพยากรย์ได้ง่าย สำหรับใครที่กำลังทำ vhost ในองค์กรสามารถใช้เทคนิคนี้ได้ครับ