Day: November 7, 2012
How to compile PHP and run it as a CGI binary
- This blog post was written using RedHat enterprise server, however the principles apply to just about any linux distro out there, it should work for them all.
- Generally what I would do is check the OS repository and see what is the next upgraded version of php its going to do, when finally you decide to do a server wide upgrade of php, and then I would go and download the source files of that version. So in this case we are going to do php 5.3.17
- Download from http://www.php.net/releases/
- Log into your server, and created a directory, then cd into it, next run the following below.
wget http://www.php.net/get/php-5.3.17.tar.gz/from/a/mirror
- Next you want to untar the file tar –zxvf <filename you downloaded>
- Next we need to get the configure flags that php is currently using, the easiest way to get this is to find a domain that has php running and setup a phpinfo.php that contains the following
<?php phpinfo() ?>
Save that file and then view it through your browser http://domain.com/phpinfo.php
You should see a php info page. If you do not see it, it probably means your owner permissions are incorrect.
Example
-rw-r–r– 1 root root 19 Nov 7 14:32 phpinfo.php (incorrect)
-rw-r–r– 1 tailor tailor 19 Nov 7 14:32 phpinfo.php (correct)
6. So at the top of that phpinfo page you should see a section called “Configure Command” Looks like what is below here.
Configure Command | ‘./configure’ ‘–disable-fileinfo’ ‘–disable-pdo’ ‘–enable-bcmath’ ‘–enable-calendar’ ‘–enable-ftp’ ‘–enable-gd-native-ttf’ ‘–enable-libxml’ ‘–enable-magic-quotes’ ‘–enable-mbstring’ ‘–enable-soap’ ‘–enable-sockets’ ‘–enable-zend-multibyte’ ‘–prefix=/usr’ ‘–with-bz2’ ‘–with-curl=/opt/curlssl/’ ‘–with-freetype-dir=/usr’ ‘–with-gd’ ‘–with-gettext’ ‘–with-imap=/opt/php_with_imap_client/’ ‘–with-imap-ssl=/usr’ ‘–with-jpeg-dir=/usr’ ‘–with-kerberos’ ‘–with-libdir=lib64’ ‘–with-libxml-dir=/opt/xml2’ ‘–with-libxml-dir=/opt/xml2/’ ‘–with-mcrypt=/opt/libmcrypt/’ ‘–with-mysql=/usr’ ‘–with-mysql-sock=/var/lib/mysql/mysql.sock’ ‘–with-mysqli=/usr/bin/mysql_config’ ‘–with-openssl=/usr’ ‘–with-openssl-dir=/usr’ ‘–with-pcre-regex=/opt/pcre’ ‘–with-pic’ ‘–with-png-dir=/usr’ ‘–with-xpm-dir=/usr’ ‘–with-zlib’ ‘–with-zlib-dir=/usr’ |
You want to copy and inside the ‘./configure—
From above example
‘./configure’ ‘–disable-fileinfo’ ‘–disable-pdo’ ‘–enable-bcmath’ ‘–enable-calendar’ ‘–enable-ftp’ ‘–enable-gd-native-ttf’ ‘–enable-libxml’ ‘–enable-magic-quotes’ ‘–enable-mbstring’ ‘–enable-soap’ ‘–enable-sockets’ ‘–enable-zend-multibyte’ ‘–prefix=/usr’ ‘–with-bz2’ ‘–with-curl=/opt/curlssl/’ ‘–with-freetype-dir=/usr’ ‘–with-gd’ ‘–with-gettext’ ‘–with-imap=/opt/php_with_imap_client/’ ‘–with-imap-ssl=/usr’ ‘–with-jpeg-dir=/usr’ ‘–with-kerberos’ ‘–with-libdir=lib64’ ‘–with-libxml-dir=/opt/xml2’ ‘–with-libxml-dir=/opt/xml2/’ ‘–with-mcrypt=/opt/libmcrypt/’ ‘–with-mysql=/usr’ ‘–with-mysql-sock=/var/lib/mysql/mysql.sock’ ‘–with-mysqli=/usr/bin/mysql_config’ ‘–with-openssl=/usr’ ‘–with-openssl-dir=/usr’ ‘–with-pcre-regex=/opt/pcre’ ‘–with-pic’ ‘–with-png-dir=/usr’ ‘–with-xpm-dir=/usr’ ‘–with-zlib’ ‘–with-zlib-dir=/usr’
7. Now you will need to make some modifications to this. I am running my php as a cgi already, but if you are running it as a module you will see in the configure flags that mysql is disabled even though it is enabled, the reason why this is because when php is run as a module, you are also loading the various flags as module extenstions to run with php and the configure flags will not reflect that on phpinfo page.
So these will be the primary flags you need to ensure are working
Note- these flags I am using are for a 64bit OS, the flags are different for a 32bit OS
This is my Example of flag functions in php I wanted to work. I copied this into a text editor and made the changes I needed accordingly, outlined below.
‘./configure’ ‘-enable-yum’ ‘–build=x86_64-redhat-linux-gnu’ ‘–host=x86_64-redhat-linux-gnu’ ‘–target=x86_64-redhat-linux-gnu’ ‘–program-prefix=’ ‘–prefix=/usr’ ‘–exec-prefix=/usr’ ‘–bindir=/usr/bin’ ‘–sbindir=/usr/sbin’ ‘–sysconfdir=/etc’ ‘–datadir=/usr/share’ ‘–includedir=/usr/include’ ‘–libdir=/usr/lib’ ‘–libexecdir=/usr/libexec’ ‘–localstatedir=/var’ ‘–sharedstatedir=/usr/com’ ‘–mandir=/usr/share/man’ ‘–infodir=/usr/share/info’ ‘–cache-file=../config.cache’ ‘–with-config-file-path=/etc’ ‘–without-config-file-scan-dir’ ‘–enable-force-cgi-redirect’ ‘–disable-debug’ ‘–enable-pic’ ‘–disable-rpath’ ‘–enable-inline-optimization’ ‘–with-bz2’ ‘–with-curl’ ‘–with-exec-dir=/usr/bin’ ‘–with-freetype-dir=/usr’ ‘–with-png-dir=/usr’ ‘–with-gd’ ‘–enable-gd-native-ttf’ ‘–with-gettext’ ‘–with-ncurses=shared’ ‘–with-gmp’ ‘–with-iconv’ ‘–with-jpeg-dir=/usr’ ‘–with-png’ ‘–with-xml’ ‘–with-libxml-dir=/usr”–with-expat-dir=/usr’ ‘–with-dom=shared,/usr’ ‘–with-dom-xslt=/usr’ ‘–with-dom-exslt=/usr’ ‘–with-xmlrpc=shared’ ‘–with-pcre-regex=/usr/include’ ‘–with-zlib’ ‘–with-layout=GNU’ ‘–enable-bcmath’ ‘–enable-exif’ ‘–enable-ftp’ ‘–enable-magic-quotes’ ‘–enable-sockets’ ‘–enable-sysvsem’ ‘–enable-sysvshm’ ‘–enable-track-vars’ ‘–enable-trans-sid’ ‘–enable-yp’ ‘–enable-wddx’ ‘–with-pear=/usr/share/pear’ ‘–with-imap=shared’ ‘–with-imap-ssl’ ‘–with-kerberos’ ‘–with-mysql=/usr’ ‘–with-unixODBC=shared,/usr’ ‘–enable-memory-limit’ ‘–enable-shmop’ ‘–enable-calendar’ ‘–enable-mbstring’ ‘–enable-mbstr-enc-trans’ ‘–enable-mbregex’ ‘–with-mime-magic=/usr/share/file/magic.mime’ ‘–enable-dba’ ‘–enable-db4’ ‘–enable-gdbm’ ‘–enable-static’ ‘–with-openssl’
- You will notice the following key thing
- You want to remove “–with-apxs2=/usr/sbin/apxs” – you can only compile one SAPI + cli at the same time. You can’t both compile CGI and the apache2 SAPI at the same time. http://bugs.php.net/bug.php?id=30682&edit=1
- You want to ensure that “–without-mysql” is changed to “–with-mysql”
- You want to ensure that you have ‘–enable-static’ (this will enable the static libraries)
- Enable any other flags you may want to use.
8. Create a file called config.sh on the server in the directory where you untarred the source php files
9. Copy the configure flags all on one line in that files and save it
10. Now run “sh config.sh” (This is will test the configure flags to see if the server can support them and it will fail on any that need dependancies installed. When you get an error on a package you generally just want to search for the development packages of the failed packages. Use Yum to install them and then run “sh config.sh” again and keep going until it finishes properly. I have listed a few common packages people run into below.
Note: sometimes you will run into path issues, like it cant find something in /usr/bin etc, what I do is do a locate of the file its looking for, usually they are .so files and simply create a simlink to where its attempting for the missing file so the configure test can complete.
yum install gcc4-c++
yum install gdbm-devel
yum install libjpeg-devel
yum install libpng-devel
yum install freetype-devel
yum install gmp-devel
yum install libc-client-devel
yum install openldap-devel
yum install mysql-devel
yum install ncurses-devel
yum install unixODBC-devel
yum install postgresql-devel
yum install net-snmp-devel
yum install bzip2-devel
yum install curl-devel
11. Once you have completed the test of the configure flags you, it will generate files at the end.
12. Now you want to run “Make” <–(DO NOT DO “MAKE INSTALL”) This will take some time to complete, if it completes successfully, you will have created a cgi binary file that will be located in “sapi/cgi/php-cgi”
Phase 2 Running Your new php cgi on your vhost
- Copy your new php-cgi binary to the cgi-bin directory or script-alias directory within your domain or vhost. This is usually “/home/username/www/cgi-bin”
Fix the permissions on the new cgi bin so that its running as the apache user or suexec user your are using for your vhost.
Ie. -rw-r–r– 1 apache:apache 19 Nov 7 14:32 php-cgi(correct)
-rw-r–r– 1 tailor:tailor 19 Nov 7 14:32 php-cgi(correct)
- Next ensure the file has executable permissions “chmod +x php-cgi“
- Now go back into the document root folder of the domain or vhost and create a .htaccess file with the following lines below and save the file.
AddHandler php-cgi .php .htm
Action php-cgi /cgi-bin/php-cgi
- As soon as you do the above the site will be using the new cgi php. If you reload the phpinfo.php page now you should see the server API read as:
Server API | CGI/FastCGI |
Note: if you want to disabled the cgi php simply comment out the lines in the .htaccess file. The cool thing about this is you don’t need to reload apache for php changes anymore, since its running as a cgi. You should check the phpinfo.php page and ensure that all the flags you wanted are listed on that page, if they are not, you either missed the flag in your configure or did not compile fully.
How to upgrade wordpress in a production environment
How to upgrade wordpress in a production environment
So I am writing this because I’m sure some people have or will run into this issue. You are running an older version of wordpress and have delayed the upgrade, in addition to delaying the upgrade you delayed the upgrade of php from 5.1.6 because your running redhat 5.
The problem with this type of upgrade is that, it’s not just a matter of upgrading wordpress, you will need to upgrade php to 5.2.x in order to use the latest version of wordpress. This can be a problem, since most people decide to run php as module and not as a cgi.
This means that you will have to upgrade php globally on the server, which could cause issues if you have not tested it and you may have to roll back if it doesn’t work. Please keep in mind you will need to do your own testing for your environments. However, if you want a solution that can give you virtually no downtime, then read on, as this is what I did when I was faced with the situation, which worked flawlessly.
So what you can do is compile your own version of php and run it as a cgi just for that one vhost or domain that you want to test, do the upgrade inside wordpress or follow the upgrade instructions that wordpress gives you. I am going to outline how to do this in this blog post.
Phase 1 Compile your own php as CGI
- Generally what I would do is check the OS repository and see what is the next upgraded version of php its going to do, when finally you decide to do a server wide upgrade of php, and then I would go and download the source files of that version. So in this case we are going to do php 5.3.17
- Download from http://www.php.net/releases/
- Log into your server and created a directory and cd into it then run the wget below.
wget http://www.php.net/get/php-5.3.17.tar.gz/from/a/mirror
- Next you want to untar the file tar –zxvf <filename you downloaded>
- Next we need to get the configure flags that php is currently using, the easiest way to get this is to find a domain that has php running and create a phpinfo.php file that contains the following
<?php phpinfo() ?>
Save that file and then view it through your browser http://domain.com/phpinfo.php
You should see a php info page. If you do not see it, it probably means your owner permissions are incorrect.
Example
-rw-r–r– 1 root root 19 Nov 7 14:32 phpinfo.php (incorrect)
-rw-r–r– 1 tailor tailor 19 Nov 7 14:32 phpinfo.php (correct)
6. So at the top of that phpinfo page you should see a section called “Configure Command” Looks like what is below here.
Configure Command | ‘./configure’ ‘–disable-fileinfo’ ‘–disable-pdo’ ‘–enable-bcmath’ ‘–enable-calendar’ ‘–enable-ftp’ ‘–enable-gd-native-ttf’ ‘–enable-libxml’ ‘–enable-magic-quotes’ ‘–enable-mbstring’ ‘–enable-soap’ ‘–enable-sockets’ ‘–enable-zend-multibyte’ ‘–prefix=/usr’ ‘–with-bz2’ ‘–with-curl=/opt/curlssl/’ ‘–with-freetype-dir=/usr’ ‘–with-gd’ ‘–with-gettext’ ‘–with-imap=/opt/php_with_imap_client/’ ‘–with-imap-ssl=/usr’ ‘–with-jpeg-dir=/usr’ ‘–with-kerberos’ ‘–with-libdir=lib64’ ‘–with-libxml-dir=/opt/xml2’ ‘–with-libxml-dir=/opt/xml2/’ ‘–with-mcrypt=/opt/libmcrypt/’ ‘–with-mysql=/usr’ ‘–with-mysql-sock=/var/lib/mysql/mysql.sock’ ‘–with-mysqli=/usr/bin/mysql_config’ ‘–with-openssl=/usr’ ‘–with-openssl-dir=/usr’ ‘–with-pcre-regex=/opt/pcre’ ‘–with-pic’ ‘–with-png-dir=/usr’ ‘–with-xpm-dir=/usr’ ‘–with-zlib’ ‘–with-zlib-dir=/usr’ |
You want to copy and inside the ‘./configure—
From above example
‘./configure’ ‘–disable-fileinfo’ ‘–disable-pdo’ ‘–enable-bcmath’ ‘–enable-calendar’ ‘–enable-ftp’ ‘–enable-gd-native-ttf’ ‘–enable-libxml’ ‘–enable-magic-quotes’ ‘–enable-mbstring’ ‘–enable-soap’ ‘–enable-sockets’ ‘–enable-zend-multibyte’ ‘–prefix=/usr’ ‘–with-bz2’ ‘–with-curl=/opt/curlssl/’ ‘–with-freetype-dir=/usr’ ‘–with-gd’ ‘–with-gettext’ ‘–with-imap=/opt/php_with_imap_client/’ ‘–with-imap-ssl=/usr’ ‘–with-jpeg-dir=/usr’ ‘–with-kerberos’ ‘–with-libdir=lib64’ ‘–with-libxml-dir=/opt/xml2’ ‘–with-libxml-dir=/opt/xml2/’ ‘–with-mcrypt=/opt/libmcrypt/’ ‘–with-mysql=/usr’ ‘–with-mysql-sock=/var/lib/mysql/mysql.sock’ ‘–with-mysqli=/usr/bin/mysql_config’ ‘–with-openssl=/usr’ ‘–with-openssl-dir=/usr’ ‘–with-pcre-regex=/opt/pcre’ ‘–with-pic’ ‘–with-png-dir=/usr’ ‘–with-xpm-dir=/usr’ ‘–with-zlib’ ‘–with-zlib-dir=/usr’
7. Now you will need to make some modifications to this. I am running my php as a cgi already, but if you are running it as a module you will see in the configure flags that mysql is disabled even though it is enabled, the reason why this is because when php is run as a module, you are also loading the various flags as module extenstions to run with php and the configure flags will not reflect that on phpinfo page.
So these will be the primary flags you need to ensure are working
Note- these flags I am using are for a 64bit OS, the flags are different for a 32bit OS
This is my Example of flag functions in php I wanted to work. I copied this into a text editor and made the changes I needed accordingly, outlined below.
‘./configure’ ‘-enable-yum’ ‘–build=x86_64-redhat-linux-gnu’ ‘–host=x86_64-redhat-linux-gnu’ ‘–target=x86_64-redhat-linux-gnu’ ‘–program-prefix=’ ‘–prefix=/usr’ ‘–exec-prefix=/usr’ ‘–bindir=/usr/bin’ ‘–sbindir=/usr/sbin’ ‘–sysconfdir=/etc’ ‘–datadir=/usr/share’ ‘–includedir=/usr/include’ ‘–libdir=/usr/lib’ ‘–libexecdir=/usr/libexec’ ‘–localstatedir=/var’ ‘–sharedstatedir=/usr/com’ ‘–mandir=/usr/share/man’ ‘–infodir=/usr/share/info’ ‘–cache-file=../config.cache’ ‘–with-config-file-path=/etc’ ‘–without-config-file-scan-dir’ ‘–enable-force-cgi-redirect’ ‘–disable-debug’ ‘–enable-pic’ ‘–disable-rpath’ ‘–enable-inline-optimization’ ‘–with-bz2’ ‘–with-curl’ ‘–with-exec-dir=/usr/bin’ ‘–with-freetype-dir=/usr’ ‘–with-png-dir=/usr’ ‘–with-gd’ ‘–enable-gd-native-ttf’ ‘–with-gettext’ ‘–with-ncurses=shared’ ‘–with-gmp’ ‘–with-iconv’ ‘–with-jpeg-dir=/usr’ ‘–with-png’ ‘–with-xml’ ‘–with-libxml-dir=/usr”–with-expat-dir=/usr’ ‘–with-dom=shared,/usr’ ‘–with-dom-xslt=/usr’ ‘–with-dom-exslt=/usr’ ‘–with-xmlrpc=shared’ ‘–with-pcre-regex=/usr/include’ ‘–with-zlib’ ‘–with-layout=GNU’ ‘–enable-bcmath’ ‘–enable-exif’ ‘–enable-ftp’ ‘–enable-magic-quotes’ ‘–enable-sockets’ ‘–enable-sysvsem’ ‘–enable-sysvshm’ ‘–enable-track-vars’ ‘–enable-trans-sid’ ‘–enable-yp’ ‘–enable-wddx’ ‘–with-pear=/usr/share/pear’ ‘–with-imap=shared’ ‘–with-imap-ssl’ ‘–with-kerberos’ ‘–with-mysql=/usr’ ‘–with-unixODBC=shared,/usr’ ‘–enable-memory-limit’ ‘–enable-shmop’ ‘–enable-calendar’ ‘–enable-mbstring’ ‘–enable-mbstr-enc-trans’ ‘–enable-mbregex’ ‘–with-mime-magic=/usr/share/file/magic.mime’ ‘–enable-dba’ ‘–enable-db4’ ‘–enable-gdbm’ ‘–enable-static’ ‘–with-openssl’
- You will notice the following key thing
- You want to remove “–with-apxs2=/usr/sbin/apxs” – you can only compile one SAPI + cli at the same time. You can’t both compile CGI and the apache2 SAPI at the same time. http://bugs.php.net/bug.php?id=30682&edit=1
- You want to ensure that “–without-mysql” is changed to “–with-mysql”
- You want to ensure that you have ‘–enable-static’ (this will enable the static libraries)
- Enable any other flags you may want to use.
8. Create a file called config.sh on the server in the directory where you untarred the source php files
9. Copy the configure flags all on one line in that files and save it
10. Now run “sh config.sh” (This is will test the configure flags to see if the server can support them and it will fail on any that need dependancies installed. When you get an error on a package you generally just want to search for the development packages of the failed packages. Use Yum to install them and then run “sh config.sh” again and keep going until it finishes properly. I have listed a few common packages people run into below.
Note: sometimes you will run into path issues, like it cant find something in /usr/bin etc, what I do is do a locate of the file its looking for, usually they are .so files and simply create a simlink to where its attempting for the missing file so the configure test can complete.
yum install gcc4-c++
yum install gdbm-devel
yum install libjpeg-devel
yum install libpng-devel
yum install freetype-devel
yum install gmp-devel
yum install libc-client-devel
yum install openldap-devel
yum install mysql-devel
yum install ncurses-devel
yum install unixODBC-devel
yum install postgresql-devel
yum install net-snmp-devel
yum install bzip2-devel
yum install curl-devel
11. Once you have completed the test of the configure flags you, it will generate files at the end.
12. Now you want to run “Make” <–(DO NOT DO “MAKE INSTALL”) This will take some time to complete, if it completes successfully, you will have created a cgi binary file that will be located in “sapi/cgi/php-cgi”
Phase 2 Running Your new php cgi on your vhost
- Copy your new php-cgi binary to the cgi-bin directory or script-alias directory within your domain or vhost. This is usually “/home/username/www/cgi-bin”
Fix the permissions on the new cgi bin so that its running as the apache user or suexec user your are using for your vhost.
Ie. -rw-r–r– 1 apache:apache 19 Nov 7 14:32 php-cgi(correct)
-rw-r–r– 1 tailor:tailor 19 Nov 7 14:32 php-cgi(correct)
- Next ensure the file has executable permissions “chmod +x php-cgi
- Now go back into the document root folder of the domain or vhost and create a .htaccess file with the following lines below and save the file.
AddHandler php-cgi .php .htm
Action php-cgi /cgi-bin/php-cgi
- As soon as you do the above the site will be using the new cgi php. If you reload the phpinfo.php page now you should see the server API read as:
Server API | CGI/FastCGI |
Note: if you want to disabled the cgi php simply comment out the lines in the .htaccess file. The cool thing about this is you don’t need to reload apache for php changes anymore, since its running as a cgi. You should check the phpinfo.php page and ensure that all the flags you wanted are listed on that page, if they are not, you either missed the flag in your configure or did not compile fully.
Phase 3. Upgrading your wordpress
- Now that you php is running under the vhost for just this wordpress site, you can log into wordpress and see if it loads properly, it should load without issues. You can either do an update from inside wordpress or do the safer way in my humble opinion and do it on the server as indicated below.
- Download the latest wordpress files to a directory inside the document root of the vhost.
- Backup your databaseBackup ALL your WordPress files in your WordPress directory. Don’t forget your .htaccess file.
- Once you have deleted the necessary files go into the directory where you untarred the new files and delete the files and directories that don’t want to overwrite in the document root (ie wp-content, wp-images, wp-includes/languages etc.)
- Then run “cp –r * ../” This will move everything from the new wordpress directory to the live document root directory.
- You should now be able to log into wordpress and see that its upgraded and functioning correctly.
- Verify the backups you created are there and usable. This is essential.
- Deactivate ALL your Plugins.
- Ensure first four steps are completed. Do not attempt the upgrade unless you have completed the first four steps.
- Delete the old WordPress files on your site, but DO NOT DELETE
- wp-config.php file;
- wp-content folder; Special Exception: the wp-content/cache and the wp-content/plugins/widgets folders should be deleted.
- wp-images folder;
- wp-includes/languages/ folder–if you are using a language file do not delete that folder;
- .htaccess file–if you have added custom rules to your .htaccess, do not delete it;
- robots.txt file–if your blog lives in the root of your site (ie. the blog is the site) and you have created such a file, do not delete it.
So now you can leave the wordpress running on the cgi php until, you pick a date to do a global php server update, at which time you can comment out the .htaccess files lines and it will revert back to using the php global version as a module.
Hope this helped you if you have questions email nick@nicktailor.com