VPS! Getting Drupal up and running on a linode

[Be sure to see the more recent update to this article,
VPS! Getting Drupal up and running on a linode (revisited)]

Well, after realizing the limitations of shared hosting for Drupal development, I decided to go with the big boys and use a dedicated server or VPS solution, at least for development. So I can make a multisite install for the docs and I can make subdomains for each development site.

So after perusing various options, I decided for linode. After checking out the various plans, I decided on the Linode 300, and got 50% more disk space by paying for a year.

While I was waiting for my account to be ready (after all today is Thanksgiving: but it still took no more than 40 minutes), I mosied over to ZoneEdit (see excellent tutorial reference below) and signed up for DNS service and domain management (free for the first 5 domains that you add to your account).

[Be sure to see the more recent update to this article,
VPS! Getting Drupal up and running on a linode (revisited)]

Well, after realizing the limitations of shared hosting for Drupal development, I decided to go with the big boys and use a dedicated server or VPS solution, at least for development. So I can make a multisite install for the docs and I can make subdomains for each development site.

So after perusing various options, I decided for linode. After checking out the various plans, I decided on the Linode 300, and got 50% more disk space by paying for a year.

While I was waiting for my account to be ready (after all today is Thanksgiving: but it still took no more than 40 minutes), I mosied over to ZoneEdit (see excellent tutorial reference below) and signed up for DNS service and domain management (free for the first 5 domains that you add to your account).

When my account was ready, the first step was to log into the Member’s area. After choosing a suitable geographic site to house my linode, I headed for the Distro Wizard and chose my friend Ubuntu (huge choice of distros, including three Ubuntu releases, including the most recent 7.10, which I chose). I used the maximum amount of disk space leaving myself with a 256 MB swap disk, typed in a root password and created the profile.

I went back to the Dashboard, which refreshed every ten seconds and soon told me that Linode Initial Configuration job, and the Disk Create from Distribution job and the Create Filesystem job were all done "Success". So… I clicked on boot and booted it! Soon found out that that job was a success too, and my Linode was Running (so said the Linode Status box).

Well, I had a domain name specified as my first free slot on ZoneEdit which already had the ZoneEdit nameservers pointing at it, so the only thing I had to do was to tell ZoneEdit to point that domain name to my new Linode. So back on my Linode Member’s area page, I clicked on the Remote Access tab, copied the ip, and specified that on the ZoneEdit edit page for my domain name (textworks.com.ar). A quick ping showed that to be an instantaneous success.

Since this is going to be a relatively permanent setup, and I might want mail to work and everything, I decided to configure textworks.com.ar as the reverse DNS for my linode ip, so I clicked on the Utilities tab, and on the Reverse DNS Configuration link, typed in textworks.com.ar and clicked on Lookup, then confirmed I wanted to change the reverse DNS configuration to textworks.com.ar (which it had found since ZoneEdit nameservers were already working). The domain showed as the current reverse DNS for the linode IP address.

Next step was to ssh into my linode! So I did in the normal way, and there I was, ssh was snappy, too.

[edit:] Bring site up to date

# apt-get update
# apt-get upgrade

I changed the hostname

/bin/hostname textworks.com.ar
echo textworks.com.ar > /etc/hostname

and rebooted (by clicking Reboot where the Boot button had originally been on the dashboard); took about one minute. And I logged in through ssh again, and did:

uname -a

and there I was: textworks.com.ar

all set.

Configure package management and update system

root@textworks:~ # cd /etc/apt 
root@textworks:/etc/apt # ls -l
total 16
drwxr-xr-x 2 root root 4096 Oct 23 08:47 apt.conf.d
-rw-r--r-- 1 root root  779 Oct 23 08:42 sources.list
drwxr-xr-x 2 root root 4096 Apr 18  2006 sources.list.d
-rw-r--r-- 1 root root 1724 Feb  8  2006 trusted.gpg
root@textworks:/etc/apt # cp sources.list sources.list.ori

Then I edited sources.list and made sure universe and multiverse repositories were enabled. (What I actually did was uncomment the universe lines, copy them and stick in multiverse for universe in the copied lines; in any case these things are pretty well documented elsewhere; you can even copy in a sources.list from your own gui-infested desktop!)

Then I did update and upgrade:

apt-get update
Then a gutsy upgrade:
apt-get upgrade 

[a little aptitude: Now folks, as an Ubuntu user, one really misses synaptic in these cases (a gui to run package management under gnome desktop, for example); however, everything we do with apt-get here, we can also do with "aptitude": just like the first thing I did on the box was to go "apt-get install mc" for trusty old midnight commander (ahh!), you can also adopt aptitude for your "command line", that is, really, terminal package management: just type in "aptitude", and I’m clicking, I’m searching, I’m seeing what’s installed…. I’m updating, I’m pointing and clicking! I used it to install phpmyadmin on the apache2 server (once LAMP was installed — see below — including a password for mysql root]

I changed the default shell to bash

root@textworks:/etc/apt # ls -lia /bin/sh
2268 lrwxrwxrwx 1 root root 4 Apr 22  2007 /bin/sh -> dash
root@textworks:/etc/apt # which bash
/bin/bash
root@textworks:/etc/apt # rm -f /bin/sh
root@textworks:/etc/apt # ln -s /bin/bash /bin/sh
root@textworks:/etc/apt # ls -lia /bin/sh
57 lrwxrwxrwx 1 root root 9 Nov 22 18:14 /bin/sh -> /bin/bash

Well, cool, now for LAMP!

First MySQL

root@textworks:/etc/apt # apt-get install mysql-server mysql-client libmysqlclient15-dev

I was asked if I wanted to set a password for MySql root, and I did.

Did some additional configuring in /etc/mysql/my.cnf to allow remote access to MySQL (this site is for development, anyway, right???) and after commenting the bind to localhost, restarted with the command:

root@textworks:~ # /etc/init.d/mysql restart

Then Apache 2

root@textworks:~ # apt-get install apache2 apache2-doc apache2-mpm-prefork apache2-utils libexpat1 ssl-cert 

Then PHP5

[edit: php5-json is part of php5-common, so removed from list (otherwise error)]
[edit: with Heron, php5-ps is no longer part of php packages (otherwise error)]
root@textworks:~ # apt-get install libapache2-mod-php5 php5 php5-common php5-curl php5-dev
php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt
php5-memcache php5-mhash php5-ming php5-mysql php5-pspell
php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl 

(well, this really is a kitchen sink approach, overkill for most people, underkill for some; but this is the command I used this time through)

Next, stuffed the following line into /etc/apache2/apache2.conf (near definition of user and group):

DirectoryIndex index.html index.htm index.cgi index.pl index.php
Then restarted apache server:
root@textworks: # apache2ctl restart

Now I tested the setup with an info.php file placed somewhere under the document root (/var/www):

root@textworks:~ # cat /var/www/info.php 
<?php phpinfo(); ?>
root@textworks:~ # 

And that worked, http://example.com/info.php nice purplish php info screen tells me I got PHP Version 5.2.3-1ubuntu6 running on Apache/2.2.4 (Ubuntu) PHP/5.2.3-1ubuntu6; cool or what?

Drupal clean url’s on ubuntu

Now, what about clean url’s on ubuntu. And something simpler than my more than one-year-old article on the subject? Basically, for Drupal clean url’s to work, the .htaccess has to work. And if you use symbolic links for drupal directories, then you better make sure Apache can follow them too. So you need to install and enable mod-rewrite and do some configuration for the Apache server. Basically, that’s it.


I configured /etc/apache2/sites-enabled/000-default.

Before (lines 10-18):

        <Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
...

After (changing AllowOverride None to AllowOverrideAll, essentially enabling .htaccess files):

         <Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
...

After doing the above configuration, I enabled the apache mod_rewrite module and restarted the apache server:

root@textworks:/etc/apache2/sites-enabled # a2enmod rewrite
Module rewrite installed; run /etc/init.d/apache2 force-reload to enable.
root@textworks:/etc/apache2/sites-enabled # apache2ctl restart

I installed and configured sendmail so Drupal will be able to… send mail

First I installed sendmail:

root@textworks:/etc/php5/apache2 # apt-get install sendmail

Then I edited php.ini:

root@textworks:/etc/php5/apache2 # vi php.ini

In this file I set the sendmail path for php around line 660:

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
sendmail_path = /usr/sbin/sendmail -i -t

Then I restarted the apache server:

root@textworks:/etc/php5/apache2 # apache2ctl restart

Now Drupal will be able to talk to me!

I did an initial document root Drupal install

Well, in the next few exciting days, weeks, and months I am sure this procedure will become more refined, security conscious, multi-site, virtual hosts, subdomains, svn repos, what-have-you (it will have a multi-site proccess flow and tracker (agile approach documentation sites) install for all my current projects, for example). However, all we want to do right this second is to get Drupal up and running.

First, I downloaded drupal and unpacked it in the document root:

root@textworks:/var/www # wget http://ftp.drupal.org/files/projects/drupal-5.3.tar.gz
root@textworks:/var/www # mv drupal-5.3.tar.gz /tmp
root@textworks:/var/www # tar xvzf /tmp/drupal-5.3.tar.gz 
root@textworks:/var/www # cd drupal-5.3/
root@textworks:/var/www/drupal-5.3 # cp -r * ..
root@textworks:/var/www/drupal-5.3 # cp .htaccess ..
root@textworks:/var/www # rm -rf drupal-5.3/

Now, I did install phpmyadmin, and it’s working great, so I could have just created the database and database user from there, but since we are in "rough and ready" "lean and mean" linode clean machine mode, and to make this narrative a little more complete, let’s do it all from the command line! Fortunately, it’s all there for you in the INSTALL.mysql.txt that comes with Drupal in the root directory, but here is what I did:

root@textworks:/var/www # mysqladmin -u root -p create dr_txtwrks  
Enter password: 
root@textworks:/var/www # mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 17
Server version: 5.0.45-Debian_1ubuntu3-log Debian etch distribution
Type 'help;' or 'h' for help. Type 'c' to clear the buffer.
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE
-> TEMPORARY TABLES, LOCK TABLES
-> ON dr_txtwrks.*
-> TO 'dr_txtwrks'@'localhost' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> quit;
Bye
root@textworks:/var/www #

So, that gave me the new database, and a new user with all the necessary privileges over that new database and over no other.

In preparation for the Drupal gui install procedure, I temporarily modified the permissions on the settings.php file:

root@textworks:/var/www # ls -l sites/default/settings.php 
-rw-r--r-- 1 root root 5976 Nov 23 06:37 sites/default/settings.php
root@textworks:/var/www # chmod 666 sites/default/settings.php  

I then pointed my browser at http://textworks.com.ar and … installed Drupal!

(who afterwards reminded me to protect settings.php:

root@textworks:/var/www # chmod 644 sites/default/settings.php 
root@textworks:/var/www # ls -l sites/default/settings.php 
-rw-r--r-- 1 root root 5982 Nov 23 06:56 sites/default/settings.php
root@textworks:/var/www # 

That’s it. It’s alive! It’s alive!

Just one more thing to do: reboot the machine to make sure the configurations are all in order:

root@textworks:~ # shutdown -r now

In a minute or two, everything was back up fine! Site up.

References

1. Ubuntu server guide: http://doc.ubuntu.com/ubuntu/serverguide/C/index.html

2a. The Perfect Setup – Ubuntu Feisty Fawn (Ubuntu 7.04): http://www.howtoforge.com/perfect_setup_ubuntu704

2b. The Perfect Server – Ubuntu Gutsy Gibbon (Ubuntu 7.10) http://www.howtoforge.com/perfect_server_ubuntu7.10

2c. Harry Sufehmi – Setting Up Linux Server – Fully Loaded

3. Addison Berry’s Install a Local Web Server on Ubuntu: http://www.lullabot.com/videocast/install-local-web-server-ubuntu

(By using aptitude instead of the X-window synaptic, you could probably just use this great video to get the job done, with the exception of one or two linode specific things).

4. Using ZoneEdit for DNS Management http://www.4webhelp.net/tutorials/misc/zoneedit.php

(excellent, step-by-step, covers many aspects, some of which are necessary for multisite setup).

[update 17 Jan 2008]

5. Jeff Beeman has just written a couple of excellent articles on this same topic, which include some interesting stuff like MySql optimization I have not dealt with.

Just got rolling with a VPS on Linode (Part 1): http://www.jeffbeeman.com/node/23

Just got rolling with a VPS on Linode (Part 2): http://www.jeffbeeman.com/node/24

[update 12 Oct 2008]

6. 2bits excellent write-up on installing Ubuntu with Drupal 6 on a VPS or dedicated server:

http://2bits.com/articles/installing-a-dedicated-server-or-a-vps-with-ubuntu-server-804-lts-hardy-heron-drupal-6x.html