Thinking of PHP, Apache, Ruby, MySQL and Unicode

Written by Arvinder Singh / February 27, 2009 / 7 mins read / Filed under Apache, / Mysql, / Php, / Ruby

In the last post, I mentioned installing Ubuntu Linux on a ppc machine. In this post we will install PHP, Ruby and MySQL.

I will be using the test server for [Drupal](http://drupal.org/ “drupal.org Community plumbing”) websites, Rails projects and possibly Lift projects. Also, I love Punjabi and I love [Unicode](http://satluj.com/ “Satluj ਆਪਣੀ ਬੋਲੀ, ਆਪਣਾ ਮਾਣ!”). So I’m going to try to make things as Unicode friendly as they can be.

Let’s start.

People love internet, internet loves images, and images love GD.

sudo aptitude search gd

It gave a numbers of options. I was confused between installing libgd or php5-gd. It turns out after

sudo aptitude install php5-gd

all other gd libraries were installed as dependencies.

Restart Apache

sudo /etc/init.d/apache2 restart

Tuning PHP/MySQL

cd /etc/php5/apache2/

By default the installations comes without a php.ini file. Rename it to php.ini-orignal.

sudo mv php.ini php.ini-orignal

Find recommended file

locate php.ini-recommended

Found it in /usr/share/doc/php5-common/examples/php.ini-recommended . Copy it to orignal php.ini localtion and rename it.

sudo cp /usr/share/doc/php5-common/examples/php.ini-recommended ./php.ini

For drupal to work properly, change session.save_handler = files to to session.save_handler = user

Restart Apache

sudo /etc/init.d/apache2 restart

MySQL fun

Login into mysql as root. By default, root mysql account has no password

mysql -u root

Lets change the mysql superuser using a hard to guess password.

mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('$a-hard-to-guess-password-here$');
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

Now lets look around

show databases;

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
+--------------------+
2 rows in set (0.01 sec)

mysql> use mysql;

mysql> show tables;

There is a table name user. Aha! This is the one with mysql user list.

mysql> desc user;

Amoung other things, it did show me three important fields - Host, User, Password

Lets look into it. Lets filter our view to just these three.

mysql> select Host,User, Password from user;

+------------------------+------------------+---------------------------------
| Host                   | User             | Password
+------------------------+------------------+---------------------------------
| localhost              | root             | *6F50F9BB1F8C9DD174B66A8087FD4FA
| xxx.xxxx.olemiss.edu   | root             | *6F50F9BB1F8C9DD174B66A8087FD4FA
| 127.0.0.1              | root             | *6F50F9BB1F8C9DD174B66A8087FD4FA
| localhost              |                  |
| xxx.xxxx.olemiss.edu   |                  |
| localhost              | debian-sys-maint | *C9D6F50F9B087D174B66A8FD4B1F8FA

What? No information in user column? Then what kind of user is it. Aha! Thats guest user also called anonymous user. So from now “O my unknown friend, I banish thee from my MySQL database.”

mysql> delete from user where User='';
Query OK, 2 rows affected (0.00 sec)

Much better. Now I have only two users(4 listed, although root is the same user using different hostnames) and debian-sys-maint. I refuse to get super-paranoid about security for now and this is good enough. (Remember I did set my root password while installation. If you have not, I strongly recommend you to.) Other thing you can do is make another user and grant limited privileges. Keep root user as a backup only with a super secure password, and do not list it in any application code.

Encoding, lets do Unicode

Now lets identify mysql database encoding. Wrong encoding can mess up non-Roman characters.

mysql> status;

Shows latin1. We want default to utf8. There might be other recommended changes too. Like PHP uses php.ini for configurations, MySQL uses my.cnf. Exit mysql.

mysql> exit
locate my-large.cnf
cp /usr/share/doc/mysql-server-5.0/examples/my-large.cnf /etc/mysql/my.cnf

Adding following to my.cnf

[client]
default-character-set = utf8

[mysqld]
skip-character-set-client-handshake
default-character-set = utf8
character-set-server = utf8
collation-server = utf8_general_ci
init-connect = SET NAMES utf8

[mysqldump]
default-character-set = utf8

[mysql]
default-character-set = utf8

Optimize my.cnf, but do not waste too much time here now. You can do it later. Keep moving. Save my.cnf and restart mysql.

Log back into mysql. Now lets create a test database and see how it goes.

mysql> create database dm_drupal;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON dm_drupal.* TO 'someuser'@'localhost' IDENTIFIED BY 'somepassword';
Query OK, 0 rows affected (0.00 sec)

Before leaving, you need to flush, otherwise changes will start stinking and fill the room.

flush privileges;

status;

The encoding is happily unicode.

Now a little MySQL benchmarking (Never fully trust benchmarks though. Remember there are lies, damned lies and benchmarks:)) Output shows 10000000 simple additions can be performed in 0.71 seconds

mysql> SELECT BENCHMARK(1000000,1+1);
+------------------------+
| BENCHMARK(1000000,1+1) |
+------------------------+
|                      0 |
+------------------------+
1 row in set (0.08 sec)

mysql> SELECT BENCHMARK(10000000,1+1);
+-------------------------+
| BENCHMARK(10000000,1+1) |
+-------------------------+
|                       0 |
+-------------------------+
1 row in set (0.71 sec)

I’m not a testing-for-a-living-guy, however what this hints me is that my database is pretty decently configured and in good shape(for now).

Setting up Virtual Hosts

I’m going to test the setting using a test installation of Drupal. First I’m going to create a virtual named host for Drupal.

cd  /etc/apache2/sites-available/
cp default drupal

Modify drupal to point to where you want to keep your installs (by default in /var/www/). I am keeping my sites in my home directory in ~/Sites directory

NameVirtualHost *
<VirtualHost *>
	ServerAdmin me@myself.com

	DocumentRoot /home/myname/Sites/drupal/

	<Directory /home/myname/Sites/drupal>
		Options Indexes FollowSymLinks MultiViews
		# AllowOverride None
		AllowOverride All
		Order allow,deny
		allow from all
	</Directory>

	ErrorLog /var/log/apache2/error.log

	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn

	CustomLog /var/log/apache2/access.log combined
	ServerSignature On

</VirtualHost>

Save and restart Apache.

To start with, I’m going to test a Drupal installation. Download drupal in your Sites folder

cd ~/Sites
wget http://ftp.drupal.org/files/projects/drupal-6.10.tar.gz
tar -xvzf drupal-6.10.tar.gz
mv drupal-6.10 to drupal

Copy settings.php in director

cp drupal/sites/default.settings.php drupal/sites/settings.php

chmod a+w drupal/sites/settings.php

We are ready. Point your browser to http://localhost to start the install process.

Enabling clean URLs

Okay now I found out apache was missing the mod-rewrite, required for clean URL’s. To enable I typed

sudo a2enmod rewrite
sudo /etc/init.d/apache2 force-reload
apache2ctl -M

The last command showed mod-rewrite was enables, however the drupal installation still could not make clean URLs. After some Googling and reading the forums, I found the solution.

Disable the site by

sudo a2dissite drupal
vi /etc/apache2/sties-available/thedmonline

find AllowOverride and change AllowOverride None to AllowOverride All at four places.

Now enable site again sudo a2ensite drupal sudo /etc/init.d/apache2 restart

Turn on the clean URL option in drupal.

Ruby 1.9

Ruby1.9 is out of beta. So is the [Pragmatic Ruby book](http://www.pragprog.com/titles/ruby3/programming-ruby-1-9 “The Pragmatic Bookshelf Programming Ruby 1.9”) (kind of).

So I rolled my sleeves up (That was a lie my friend, added to give drama… I was wearing a half sleeve t-shirt).

wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p0.tar.gz
tar xvzf ruby-1.9.1-p0.tar.gz
cd ruby-1.9.1-p0
sudo aptitude install build-essential libssl-dev libreadline5-dev
./configure --prefix=/usr/local
make && make install

Okay I rolled my (virtual)sleeves down. Lets test

ruby -v # ruby 1.9.1p0 (2009-01-30 revision 21907) [powerpc64-linux]

The post has gone too long(Who cares, its for my own documentation). In the next post, we get to managing development using new content versioning kid around the block, git. We’ll probe how to install multiple Drupal and Ruby sites using Git and how it can co-exist and interact with CVS/SVN.