background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount
Eric.London's picture

When Centos came out with php53* packages, I promptly upgraded to test them out. I did not get around to installing PECL and memcache until recently, and soon realized they were no longer available. This article shows how I was able to install PECL and memcache on a Centos (5.6) system using the IUS repository.

Since I am running the php53* packages, the provided php-pecl-memcache package is not compatible. Checking what PECL packages are available:

$ yum list | grep -i ^php.*pecl
php-pecl-Fileinfo.x86_64                 1.0.4-3.el5.centos     extras         
php-pecl-fileinfo.x86_64                 1.0.4-2.el5.rf         rpmforge       
php-pecl-http.x86_64                     1.6.5-2.el5.rf         rpmforge       
php-pecl-mailparse.x86_64                2.1.5-2.el5.rf         rpmforge       
php-pecl-memcache.x86_64                 2.2.5-2.el5.rf         rpmforge       
php-pecl-session_mysql.x86_64            1.9-2.el5.rf           rpmforge       
php-pecl-ssh2.x86_64                     0.11.0-1.el5.rf        rpmforge       
php-pecl-zip.x86_64                      1.8.10-2.el5.rf        rpmforge       

I decided to try out the IUS repository which provides a new set of php53 packages, along with pecl and memcache.

# downloading packages
$ wget http://dl.iuscommunity.org/pub/ius/stable/Redhat/5.5/x86_64/ius-release-...
$ wget http://dl.iuscommunity.org/pub/ius/stable/Redhat/5.5/x86_64/epel-release...

# installing packages
$ rpm -Uvh ius-release-1.0-6.ius.el5.noarch.rpm
$ rpm -Uvh epel-release-1-1.ius.el5.noarch.rpm

The IUS packages are also not compatible with the installed php53* packages, so I removed them and installed the new php53u* packages.

# checking which are currently installed
$ yum list | grep -i ^php.*installed
php53.x86_64                            5.3.3-1.el5_6.1         installed      
php53-cli.x86_64                        5.3.3-1.el5_6.1         installed      
php53-common.x86_64                     5.3.3-1.el5_6.1         installed      
php53-devel.x86_64                      5.3.3-1.el5_6.1         installed      
php53-gd.x86_64                         5.3.3-1.el5_6.1         installed      
php53-mbstring.x86_64                   5.3.3-1.el5_6.1         installed      
php53-mysql.x86_64                      5.3.3-1.el5_6.1         installed      
php53-pdo.x86_64                        5.3.3-1.el5_6.1         installed

# removing existing:
$ yum remove php53*

# installing IUS packages:
$ yum install php53u php53u-cli php53u-common php53u-devel php53u-gd php53u-mbstring php53u-mysql php53u-pdo php53u-pear php53u-pecl-apc php53u-xml php53u-xmlrpc php53u-pecl-memcache

Next, I installed the memcached service.

# install
$ yum install memcached

# set run levels
$ chkconfig --level 2345 memcached on

# start service
$ /etc/init.d/memcached start

After installation, I restarted Apache and checked to ensure memcache was not working.

$ php -i | grep -i memcache\ support
memcache support => enabled

I created a tiny script to test for memcache support:

<?php
$memcache
= new Memcache;
$memcache->connect('127.0.0.1', 11211);
print_r($memcache);
?>

$ php memcachetest.php
Memcache Object
(
    [connection] => Resource id #4
)

Now, my system is ready to begin work with the Memcache API and Integration Drupal module :)

In this article, I'll show the commands I have been using to set up a fresh Centos server, configured for Apache, MySQL, PHP, Tomcat, Drupal, and Apache Solr. For my article, I used Parallels to create a virtual machine from the Centos 5.6 64bit ISOs I downloaded. To simply this article, all commands are being executed as root, firewall configurations and performance tweaks are not accounted for.

Once the distribution is installed, the first thing I do is upgrade all packages.

$ yum update

Install PHP, Apache, and MySQL

$ yum install php53 php53-gd php53-mbstring php53-mysql php53-xml mysql-server httpd

Set runlevels for Apache and MySQL

$ chkconfig --level 2345 httpd on
$ chkconfig --level 2345 mysqld on

Install subversion. I chose to use subversion for this article because the Drupal 6.x installation works well with svn:externals to fetch the SolrPhpClient library. All subversion commands are connecting to a local subversion repository. If you are using an external server (like Beanstalk), you will have to transpose all commands from using "file://" to "https://".

$ yum install subversion

Add a new local subversion repository (OPTIONAL).

$ mkdir /var/subversion
$ svnadmin create /var/subversion/example.com
$ svn mkdir file:///var/subversion/example.com/trunk -m "added trunk"
$ svn mkdir file:///var/subversion/example.com/branches -m "added branches"
$ svn mkdir file:///var/subversion/example.com/tags -m "added tags"

Download/setup drush

$ cd /var/www
$ wget http://ftp.drupal.org/files/projects/drush-7.x-4.4.tar.gz
$ tar -xzf drush-7.x-4.4.tar.gz
$ ln -s /var/www/drush/drush /usr/local/bin/drush

Create a vhost location on the server for the Drupal installation.

$ mkdir /var/www/vhosts
$ cd /var/www/vhosts
$ drush dl drupal
$ mv drupal-7.0/ example.com

Integrate the Drupal files with subversion

$ cd /var/www/vhosts/example.com
$ svn co file:///var/subversion/example.com/trunk .
$ svn add * .htaccess
$ svn commit -m "downloaded drupal"

Download the Drupal apachesolr module

# make a folder for contrib modules
$ mkdir /var/www/vhosts/example.com/sites/all/modules/contrib
$ cd /var/www/vhosts/example.com/sites/all/modules/contrib

# note: in the below command, you may be prompted to choose which version of the Solr module to install. I choose option 2 for the Supported version
$ drush dl apachesolr

# commit to subversion
$ cd /var/www/vhosts/example.com/sites/all/modules
$ svn add contrib
$ svn commit -m "added contrib folder and apachesolr module"

Setup MySQL

# start mysql
$ /etc/init.d/mysqld start

# set root password
$ /usr/bin/mysqladmin -u root password 'new-password'

# create new database, user, and set permissions
$ mysql --execute="create database db_example"
$ mysql --execute="grant all privileges on db_example.* to 'example-user'@'localhost' identified by 'some_password'"

Setup Apache vhost

$ cd /etc/httpd/conf.d

# create a new file "example.com.conf", with the contents:

NameVirtualHost *:80

<Directory /var/www/vhosts>
  AllowOverride All
</Directory>

<VirtualHost *:80>
  ServerName example.com
  DocumentRoot /var/www/vhosts/example.com
  ErrorLog logs/example.com-error_log
  CustomLog logs/example.com-access_log common
</VirtualHost>

Reset Apache file permissions. NOTE: you will need a more solid/secure configuration for this!

$ cd /var/www
$ chown -R apache.apache drush*
$ chown -R apache.apache vhosts

Start Apache

$ /etc/init.d/httpd start

Install Drupal via drush

$ cd /var/www/vhosts/example.com

# note: you can set your user 1 username, password, email, etc in the following command if desired. type "drush help si" for more install options
$ drush site-install standard --sites-subdir=example.com --db-url=mysqli://example-user:some_password@localhost/db_example

At this point, you should be able to browse to your site and it will be up and running.
Drupal Installed

Now, we move onto Tomcat and Solr!

Installing Tomcat and Java. The default Centos yum repositories provide Tomcat5. I prefer Tomcat6, so there are some extras steps below and a dependency issue I had to resolve.

# added repo file to get tomcat6:
$ cd /etc/yum.repos.d/
$ wget http://www.jpackage.org/jpackage50.repo

# install Java JDK:
$ yum install java-1.6.0-openjdk

# install tomcat6:
$ yum install tomcat6 tomcat6-admin-webapps tomcat6-webapps

# dang, dependency issue... (!)

java-1.4.2-gcj-compat-1.4.2.0-40jpp.115.x86_64 from base has depsolving problems
  --> Missing Dependency: /usr/bin/rebuild-security-providers is needed by package java-1.4.2-gcj-compat-1.4.2.0-40jpp.115.x86_64 (base)
Error: Missing Dependency: /usr/bin/rebuild-security-providers is needed by package java-1.4.2-gcj-compat-1.4.2.0-40jpp.115.x86_64 (base)
You could try using --skip-broken to work around the problem
You could try running: package-cleanup --problems
                        package-cleanup --dupes
                        rpm -Va --nofiles --nodigest
The program package-cleanup is found in the yum-utils package.

# Fixing dependency issue (OPTIONAL):
$ mkdir ~/downloads
$ cd ~/downloads
$ wget http://plone.lucidsolutions.co.nz/linux/centos/images/jpackage-utils-com...
$ rpm -Uvh jpackage-utils-compat-el5-0.0.1-1.noarch.rpm
$ yum install tomcat6 tomcat6-admin-webapps tomcat6-webapps

# setting tomcat runlevels
$ chkconfig --level 2345 tomcat6 on

# starting tomcat
$ /etc/init.d/tomcat6 start

At this point, you should be able to access Tomcat in your browser (http://example.com:8080)
Tomcat homepage

Downloading Solr Java library.

$ cd ~/downloads
# note: you may need to choose a different mirror to download
$ wget http://www.fightrice.com/mirrors/apache//lucene/solr/1.4.1/apache-solr-1...
$ tar -xzf apache-solr-1.4.1.tgz

# copy/rename solr war file into Tomcat webapps directory
$ cp ~/downloads/apache-solr-1.4.1/dist/apache-solr-1.4.1.war /var/lib/tomcat6/webapps/solr.war

# copy solr files
$ cp -r ~/downloads/apache-solr-1.4.1/example/solr/ /var/lib/tomcat6/solr/

Copying the java war file into the Tomcat webapps folder will create this directory automatically:

/var/lib/tomcat6/webapps/solr

Create Catalina config file to link war file to solr directory:

$ cd /etc/tomcat6/Catalina/localhost

# create new file: "solr.xml", with the contents:

<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/var/lib/tomcat6/webapps/solr.war" debug="0" privileged="true" allowLinking="true" crossContext="true">
<Environment name="solr/home" type="java.lang.String" value="/var/lib/tomcat6/solr" override="true" />
</Context>

Setup Tomcat admin user(s):

# edit file: /etc/tomcat6/tomcat-users.xml, ensure similar contents exist:

<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="admin"/>
<role rolename="manager"/>
<user username="eric" password="supersecretpassword" roles="admin,manager"/>
</tomcat-users>

Update WEB-INF/web.xml file:

# edit file: /var/lib/tomcat6/webapps/solr/WEB-INF/web.xml, update section to reflect solr path:

<env-entry>
  <env-entry-name>solr/home</env-entry-name>
  <env-entry-value>/var/lib/tomcat6/solr</env-entry-value>
  <env-entry-type>java.lang.String</env-entry-type>
</env-entry>

Copy conf files from Drupal apachesolr module into Tomcat Solr conf directory (overwrite):

$ cp /var/www/vhosts/example.com/sites/all/modules/contrib/apachesolr/protwords.txt /var/lib/tomcat6/solr/conf/
$ cp /var/www/vhosts/example.com/sites/all/modules/contrib/apachesolr/schema.xml /var/lib/tomcat6/solr/conf/
$ cp /var/www/vhosts/example.com/sites/all/modules/contrib/apachesolr/solrconfig.xml /var/lib/tomcat6/solr/conf/

Reset Tomcat permissions/ownership:

$ cd /var/lib
$ chown -R tomcat.tomcat tomcat6/

Restart Tomcat

$ /etc/init.d/tomcat6 restart

At this point, you should be able to access the solr/admin tomcat Page (http://example.com:8080/solr/admin)
Solr Admin

If things are not working well at this point, check the Tomcat logs:

/var/log/tomcat6/catalina.out

And, ensure the solr java module is listed in the Tomcat Web Application Manager: http://example.com:8080/manager/html

If all is well, you can now enable the Drupal apachesolr modules:

$ cd /var/www/vhosts/example.com
$ drush en apachesolr apachesolr_search apachesolr_taxonomy apachesolr_access --uri=example.com

Log into your Drupal site. NOTE: default account (via drush): admin/admin

Edit default Apache Solr Host Settings:
URL: http://example.com/admin/config/search/apachesolr/server/solr/edit
Change url to: http://example.com:8080/solr, and save form.

Go to Drupal search settings page:
URL: http://example.com/admin/config/search/settings
Change the default search mode to "Apache Solr search", and save form.

Now, you are ready to test the indexing and integration.

Add a new piece of content to test indexing.
# Example:
# http://example.com/node/add/article
# title: Test Article
# Body: test test test

Browse to solr index page:
URL: http://example.com/admin/config/search/apachesolr/index
Select: Index queued content, and click on Begin button
You should see a status message like: "1 item processed successfully." and "Number of documents in index: 0 (1 sent but not yet processed)"
A few minutes later, refreshing the index page should show: "Number of documents in index: 1"

Search for "test" to verify Solr results.
URL: http://example.com/search/site/test
Solr Search Results

You can also review search results via solr/admin
URL: http://example.com:8080/solr/admin/
Enter "test" in query string box and click search

Part 2, Multicore Configuration (OPTIONAL)

If you need to run multiple sites off a single Solr Tomcat installation, you can setup multicore..

Copy the multicore xml file into your solr directory:

$ cp ~/downloads/apache-solr-1.4.1/example/multicore/solr.xml /var/lib/tomcat6/solr/

Create a new directory for each multisite in the solr directory:

$ mkdir /var/lib/tomcat6/solr/example.com

Replicate the solr conf directory into the new multisite directory:

cp -r /var/lib/tomcat6/solr/conf /var/lib/tomcat6/solr/example.com/conf/

Update the solr.xml file:

# edit file: /var/lib/tomcat6/solr/solr.xml, added <core> section for each site:
<cores adminPath="/admin/cores">
  <core name="example.com" instanceDir="example.com" />
</cores>

Restart Tomcat

$ /etc/init.d/tomcat6 restart

Now, your new multicore site will be accessible here: http://example.com:8080/solr/example.com/admin/

Eric.London's picture

In this tutorial I'll show how you can setup a server to parse email with a PHP script. This tutorial assumes that your server is configured to receive email (I wrote this using a virtual machine running postfix).

The first thing you'll need to do is configure an alias to direct email to a PHP script (instead of an email box). I added the following entry to the bottom of my /etc/aliases file and then ran the "newaliases" command to refresh my aliases database:

phpscript: "|php -q /usr/local/bin/email.php"

The above entry will pipe email sent to phpscript@MYDOMAIN to the designated PHP script.

And here's the script:

#!/usr/bin/php
<?php

// fetch data from stdin
$data = file_get_contents("php://stdin");

// extract the body
// NOTE: a properly formatted email's first empty line defines the separation between the headers and the message body
list($data, $body) = explode("\n\n", $data, 2);

// explode on new line
$data = explode("\n", $data);

// define a variable map of known headers
$patterns = array(
 
'Return-Path',
 
'X-Original-To',
 
'Delivered-To',
 
'Received',
 
'To',
 
'Message-Id',
 
'Date',
 
'From',
 
'Subject',
);

// define a variable to hold parsed headers
$headers = array();

// loop through data
foreach ($data as $data_line) {

 
// for each line, assume a match does not exist yet
 
$pattern_match_exists = false;

 
// check for lines that start with white space
  // NOTE: if a line starts with a white space, it signifies a continuation of the previous header
 
if ((substr($data_line,0,1)==' ' || substr($data_line,0,1)=="\t") && $last_match) {

   
// append to last header
   
$headers[$last_match][] = $data_line;
    continue;

  }

 
// loop through patterns
 
foreach ($patterns as $key => $pattern) {

   
// create preg regex
   
$preg_pattern = '/^' . $pattern .': (.*)$/';

   
// execute preg
   
preg_match($preg_pattern, $data_line, $matches);

   
// check if preg matches exist
   
if (count($matches)) {

     
$headers[$pattern][] = $matches[1];
     
$pattern_match_exists = true;
     
$last_match = $pattern;

    }

  }

 
// check if a pattern did not match for this line
 
if (!$pattern_match_exists) {
   
$headers['UNMATCHED'][] = $data_line;
  }

}

?>

At this point in the code, the body of the message will be contained in the $body variable and the headers will be in $headers.

Here is an example of the parsed headers (using print_r()):

Array
(
    [UNMATCHED] => Array
        (
            [0] => From root@Eric-Centos.localdomain  Sun Jan 10 21:49:50 2010
        )

    [Return-Path] => Array
        (
            [0] => <root@Eric-Centos.localdomain>
        )

    [X-Original-To] => Array
        (
            [0] => phpscript
        )

    [Delivered-To] => Array
        (
            [0] => phpscript@Eric-Centos.localdomain
        )

    [Received] => Array
        (
            [0] => by Eric-Centos.localdomain (Postfix, from userid 0)
            [1] => id 4D03F30131; Sun, 10 Jan 2010 21:49:50 -0500 (EST)
        )

    [To] => Array
        (
            [0] => phpscript@Eric-Centos.localdomain
        )

    [Subject] => Array
        (
            [0] => This is the subject
        )

    [Message-Id] => Array
        (
            [0] => <20100111024950.4D03F30131@Eric-Centos.localdomain>
        )

    [Date] => Array
        (
            [0] => Sun, 10 Jan 2010 21:49:50 -0500 (EST)
        )

    [From] => Array
        (
            [0] => root@Eric-Centos.localdomain (root)
        )

)

Now, you have all the email headers and message body parsed. You can do whatever your heart desires with the data, like insert it into a database or even create nodes!

I recently got a new MacBook Pro laptop (awesome!) and went through my usual rigmarole of setting up a new [VirtualBox] virtual machine for LAMP development. In previous situations I used bridged network connections which allow my virtual machine to have its own network connection, and acquire an IP address via DHCP. Now that I plan on being more mobile, I was concerned about having a static IP address for my virtual machine (for samba connections, scripting, and any other processes that relies on a static IP address). I decided to explore alternative virtual network connections and changed my virtual NIC to use NAT (the default network connection for VirtualBox). This configuration establishes a virtual NAT for your virtual machines which is great, but the downside is I know have to setup port forwarding to connect to my virtual machine. In bridged network configurations, I could simply SSH or use Samba to connect to my virtual machine by IP address. With NAT I have to setup port forwarding for the services I need to connect to. Initially I decided to setup port forwarding for SSH (port 22) and HTTP (port 80). While my virtual machine was powered down, I executed the following commands. NOTE: you'll have to replace "Centos" with the name of your virtual machine.

$ VBoxManage setextradata "Centos" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/Protocol" TCP
$ VBoxManage setextradata "Centos" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/GuestPort" 22
$ VBoxManage setextradata "Centos" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/HostPort" 2222
$ VBoxManage setextradata "Centos" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guesthttp/GuestPort" 80
$ VBoxManage setextradata "Centos" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guesthttp/HostPort" 8080

Now, I can SSH to my virtual machine..

$ ssh -p 2222 Eric@localhost

Or, connect to Apache by browsing to http://localhost:8080

The benefit of this network configuration allows me to travel anywhere with my laptop, use any type of network connection, and not have to worry about changing the way I connect to my virtual machine for development.

Eric.London's picture

This morning, I encountered a PHP fatal error on my development environment. Upon further inspection, one of my third party modules (XML Sitemap) required a later version of PHP. A fresh installation of Centos 5.3 comes with version 5.1.6 of PHP. Here is an easy way to upgrade PHP to a later version by using the Utter Ramblings Yum repository.

I created a new yum repo file:

$ sudo emacs /etc/yum.repos.d/utterramblings.repo

# FILE CONTENTS - START
[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka
# FILE CONTENTS - END

Ran a yum update:

$ sudo yum update
# ...snip...
Updated: apr.i386 0:1.2.12-2.jason.1 apr-util.i386 0:1.2.12-5.jason.1 curl.i386 0:7.15.5-2.1.el5_3.5 httpd.i386 0:2.2.8-jason.3 ksh.i386 0:20080202-2.el5_3.1 mod_ssl.i386 1:2.2.8-jason.3 mysql.i386 0:5.0.58-jason.2 mysql-server.i386 0:5.0.58-jason.2 pcre.i386 0:7.6-jason.1 php.i386 0:5.2.6-jason.1 php-cli.i386 0:5.2.6-jason.1 php-common.i386 0:5.2.6-jason.1 php-gd.i386 0:5.2.6-jason.1 php-mbstring.i386 0:5.2.6-jason.1 php-mssql.i386 0:5.2.6-jason.1 php-mysql.i386 0:5.2.6-jason.1 php-odbc.i386 0:5.2.6-jason.1 php-pdo.i386 0:5.2.6-jason.1 php-pear.noarch 1:1.6.2-1.jason.1 php-xml.i386 0:5.2.6-jason.1 php-xmlrpc.i386 0:5.2.6-jason.1 subversion.i386 0:1.4.4-jason.1 tzdata.noarch 0:2009k-1.el5
Complete!

After updating all these packages, I checked out my new PHP version:

$ php -v | head -1
PHP 5.2.6 (cli) (built: May  5 2008 10:32:59)

Now, my PHP fatal error has been resolved.

NOTE: This blog entry is a re-post of a previous article.

Syndicate content