Lucidly Drupal: Setting up Ubuntu 10.4 Lucid LAMP stack for your Drupal site

We're frequently setting up servers for development, for staging, for production. I've lately preferred the Debian flavor of Linux, but up until now that had been something of a problem because Debian and Ubuntu did not include the higher-quality php5-gd library, which meant that you either had to compile your own PHP, pull from an alternative source host, or cope with substandard image resizing with limited processing features.

But now we have Ubuntu 10.4 LTS "Lucid" and life is good. Lucid comes with PHP 5.3.x and the proper GD2 library! (Cheers. Applause.)

Still, there's a lot of little steps to set up to get your server (or virtual private server) up and running and ready for Drupal. It's not hard, just detail-oriented work you don't want to do when you're bleary-eyed at the end of the day. In my repetitions of doing this over and over, I've collected some notes, and I thought I'd post them here for my own reference, and perhaps your reference as well. My thanks to our own Brian Vuyk for guidance on the APC installation.

[Edit: Brian also pointed me to Taskel as another way to go. I've not tried it that way yet, so this post doggedly sticks to the step-by-step for now.]

Lucidly Drupal: Setting up Ubuntu 10.4 Lucid LAMP stack for your Drupal site
Drupal requires some things, and likes some other things a lot. Here's how to configure the latest Ubuntu Linux to make Drupal happy.

Assumptions

  • You already have Ubuntu 10.4 installed on your server.
  • You know your server's IP address.
  • You already have root or sudo access.
  • You want to set up for Drupal. (Of course, many CMSs and blog platforms will have similar requirements, and this post may have some appeal and relevance to people using those tools. But in this post I'm aiming at the particulars for Drupal.)
  • You have a computer with shell access to your server, or a properly configured *AMP setup on your computer. (This post does not cover MAMP, WAMP, DAMP or commandline bootcamp.)

Step by Step

  1. Initial Preparation

    1. Create a public key.

      If you do this, you can connect to your server without having to log in. It's also necessary if you want to deploy from a provisioning system or repository like GitHub.

      ssh-keygen -t rsa -C "yourname@example.com"
      

      Note: For deployment purposes, you need to generate the key as the user who will be executing the checkouts. For example, if you checkout as root, you will need to be logged in as root when generating the key.

      To print out the key (to copy and paste into GitHub, for example):

      cat ~/.ssh/id_rsa.pub
    2. Install security updates.

      FIrst things first.

      apt-get update
      apt-get upgrade --show-upgraded
      

      Note that if you are using a regular shell user account with sudo, you will want to prepend pretty much all commands in this guide with "sudo". For example: sudo apt-get update would be the first command above.

    3. Set your hostname

      You should give your machine a name. This is a machine name for your server. It does mean anything about your domain or what URL you want to use for your site. For this example, we'll use the name "athena":

      echo "athena" > /etc/hostname
      hostname -F /etc/hostname
      

      Next, edit the file "/etc/hosts". There are a few options for text editor within Linux. I find nano to be easy to use.

      nano /etc/hosts
      

      [NB: In these instructions, your server's IP address is represented by "12.34.56.78". Every time you see that sequence in the examples here, you should replace them with your server's IP address. Also replace "athena" everywhere it appears with your server's name, and "example.com" with your actual domain.]

      127.0.0.1        localhost.localdomain        localhost
      12.34.56.78      athena.example.com             athena

      athena.example.com is your "fully qualified domain name" or FQDN. (You will come across this from time to time.)

    4. Set your server's base timezone

      This part is easy:

      dpkg-reconfigure tzdata

      You will get pop-up prompts for country, etc. and that's done!

  2. Set up VirtualHost stuff

    1. Install Apache

      First things first.

      apt-get install apache2
    2. Edit /etc/apache2/ports.conf
      nano /etc/apache2/ports.conf
      

      Replace *:80 with your IP address, so it looks like this:

      NameVirtualHost 12.34.56.78:80
    3. Edit /etc/apache2/sites-available/default
      nano /etc/apache2/sites-available/default
      

      Edit as such:

      <VirtualHost 12.34.56.78:80>

      You will also want to update the DocumentRoot value to where you intend to install your Drupal root.

      DocumentRoot /var/www/example.com/html
    4. Configure name-based virtual hosts

      Create a file in

      /etc/apache2/sites-available/

      for each of your sites on the server.

      nano /etc/apache2/sites-available/example1.com
      
      <VirtualHost 12.34.56.78:80>
           ServerAdmin admin@example1.com
           ServerName example1.com
           ServerAlias www.example1.com
           DocumentRoot /var/www/example1.com/html/
           ErrorLog /var/www/example1.com/logs/error.log
           CustomLog /var/www/example1.com/logs/access.log combined
      </VirtualHost>

      Repeat this process for each site you are setting up. Note that separate sites will have different DocumentRoot values, while a multisite setup will share the same DocumentRoot value.

      Git note: If you are going to deploy using Git (covered in the next step below), you want to define your DocumentRoot to include your Git repository name and any internal paths to your Drupal document root. For example, if you are installing from a GitHub project titled "foobar" and inside of it you have a folder "html" that contains your Drupal installation, your DocumentRoot value would be /var/www/example.com/foobar/html/.

    5. Create your website folders
      • First, create the folder for your logs.
        mkdir -p /var/www/example.com/logs
        

        This command will create your logs folder, and the domain folder containing it.

      • Now create your website html folder(s).

        How you do this depends upon how you're going to install your site on the server.

        If you are using scp or sftp or otherwise copying your Drupal code files onto the server, you will want to create the folder to hold them. Remember that your DocumentRoot value you entered above must match where your actual document root ends up being on the server.

        If you are going to be deploying via Git, you don't need to do that: Git will create it when you git clone the repository onto the server into /var/www/example.com/.

    6. Enable the virtual domain
      a2ensite example.com
      

      Do this command for each domain or subdomain you're configuring here.

    7. Reload Apache
      /etc/init.d/apache2 reload
      

    Assuming that you have configured the DNS for your domain to point to your server's IP address, virtual hosting for your domain should now work.

    Of course, there's still more server prep to do so you can run Drupal....

  3. Build PHP, MySQL and the goodness Drupal loves

    1. MySQL Installation

      First install the thing.

      apt-get install mysql-server
      

      You will be prompted to create the MySQL root password, and re-enter it.

      Now we secure the installation.

      mysql_secure_installation
      

      You will be prompted to set/change the MySQL root password and other things. You won't need to change the MySQL root password, but you probably want to answer "Y" yes to the other questions.

    2. Create your database

      Log into MySQL.

      mysql -u root -p
      

      The -u defines the mysql user, which in this case is mysql root user, 'root'. You will be prompted for the MySQL root password. When you get a prompt like this:

      mysql>
      

      …you're in!

      Now create your database. [In this example, the database name is 'foobar', the database user is 'rumpole', and the user password is 'p4ssw0rd'. Change these to the actual database name, database user and passwords you want for your database. Be sure to note these down, because you'll need this info when you set up your Drupal site.]

      create database foobar CHARACTER SET utf8 COLLATE utf8_general_ci;
      

      [Update: You need to set the CHARACTER SET and COLLATE values, as shown above, or MySQL will default to non-recommended latin1 / latin_swedish_ci.]

      Note the ';' at the end of the line. That is required for MySQL to execute the command.

      Define the user and permissions for the database. I'll keep it easy here:

      grant all on foobar.* to 'rumpole' identified by 'p4ssw0rd';
      

      Now wrap this up and quit MySQL:

      flush privileges;
      
      quit
      
    3. Install PHP

      Use apt-get to pull down the packages.

      apt-get install php5 php5-dev php-pear php5-gd
      

      Note that php5-dev is not necessarily required, except you will need it later for the PECL installation of UploadProgress (which is very nice to have for the Drupal user interface). php5-gd is to enable nice image handling.

    4. Configure the php.ini settings.

      Edit the appropriate php.ini file:

      nano /etc/php5/apache2/php.ini
      

      This is a big file. You will need to search through the file to find these value configurations.

      You will want to boost the default memory limit value.

      memory_limit: 128M

      (128MB is the default for Lucid. If you're running a lot of modules, or some heavy processes, you may need to increase this memory_limit value even higher.)

      Now, while you in php.ini, make sure that the following lines are uncommented and have proper values established.

      max_execution_time = 30
      error_reporting = E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR
      display_errors = Off
      log_errors = On
      error_log = /var/log/php.log
      register_globals = Off
      safe_mode = Off
      session.cache_limiter: nocache

      You will also need to add lines for PDO support. Find the Dynamic Extensions area in the file, and add these lines:

      extension=php_pdo.dll
      extension=php_pdo_mysql.dll

      [Edit: You don't need to add these in Ubuntu 10.04. As it happens, Lucid comes with PDO extensions already enabled. Thanks to Peter Wolanin for pointing out in comments below what should have been obvious about .dll extensions in Linux. #facepalm]

      Refer to http://drupal.org/requirements for details and nuances on php settings.

      To have these take effect, restart apache.

      /etc/init.d/apache2 restart
      
    5. Install PHP MySQL and Security Packages
      1. Let's start with MySQL.
        apt-get install php5-mysql
        
      2. Update your sources.

        Now be sure the following lines in /etc/apt/sources.list are uncommented:

        nano /etc/apt/sources.list
        
        deb http://us.archive.ubuntu.com/ubuntu/ lucid universe
        deb-src http://us.archive.ubuntu.com/ubuntu/ lucid universe
        deb http://us.archive.ubuntu.com/ubuntu/ lucid-updates universe
        deb-src http://us.archive.ubuntu.com/ubuntu/ lucid-updates universe

        deb http://security.ubuntu.com/ubuntu lucid-security universe
        deb-src http://security.ubuntu.com/ubuntu lucid-security universe

      3. Update what you have so far.
        apt-get update
        
      4. Boost security a bit.

        Now install the php5-suhosin package to provide additional security.

        apt-get install php5-suhosin
        
      5. Restart apache.

        To have these take effect, restart apache.

        /etc/init.d/apache2 restart
        
    6. Enable mod_rewrite

      This is easy peasy in Ubuntu because the PHP module is already installed; you just need to enable it:

      a2enmod rewrite
      

      And restart apache again:

      /etc/init.d/apache2 restart
      
    7. Install PECL UploadProgress.

      This allows you to have that nifty upload progress display when uploading files. It's not required, but is useful user feedback, which I recommend highly.

      1. First, update.
        apt-get update
        
      2. Run the PECL installation of UploadProgress.
        pecl install uploadprogress
        
      3. Now save the setting.

        Note: This is all one line!

        echo "extension = uploadprogress.so" > /etc/php5/apache2/conf.d/uploadprogress.ini 
        
      4. Reload Apache to have it take effect.
        /etc/init.d/apache2 reload
        

      Done!

  4. Optional

    1. Install Git

      If you want to use Git to deploy your site code, you will need to install Git itself.

      apt-get install git-core
      
    2. Install Drush and Drush Make

      Drush installation instructions are in the Drush readme.txt file.

    3. Install APC
      apt-get install libpcre3-dev
      pecl install apc
      

      Then edit your php.ini file to add to the extensions area:

      ; APC
      extension=apc.so;
      apc.shm_size=64M;

      Then you can copy over a php file that offers some nice stats:

      cp /usr/share/php/apc.php /var/www/example.com/html/apc.php
      

      Note that the path of the destination is your webroot.

      Then restart apache.

      /etc/init.d/apache2 restart
      

      And you're done. You will be able to get some nice APC stats at http://example.com/apc.php. (You can always protect that file via .htaccess to put an authentication password on it if you like.)

    4. Install fail2ban

      Fail2ban is a nice little security addition.

      apt-get install fail2ban
      

      That's all on that.

    5. Install bash-completion

      Bash-completion is a new one for me, and is turning out to be very handy. How did I go so long in the dark?

      apt-get install bash-completion
      

And that's it. Now your system is ready for site deployment to the folder you defined. Note that after you've deployed your site you will also want to set up a cron job.

IANASA

I am not a sysadmin by profession. This is just documentation of what I do for my own projects, or when tossing up a staging server for one of our in-house or client projects. Any tips for improvement, corrections, etc. are most welcome.

Update: Clean URLs problem?

Recently I've run into an added complication with setting up Lucid: clean urls were not working. rewrite_module was enabled, .htaccess was there, but no go. As it turns out, .htaccess was not being read by default. If this happens to you, here's a fix:

Edit the default site configuration in sites-available:

nano /etc/apache2/sites-enabled# 000-default 

A few lines down, under the directory pointing to you docroot, you need to change "AllowOverride None" to "AllowOverride all".

<Directory /var/www/[pathtoyourwebroot]>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride all
                Order allow,deny
                allow from all
        </Directory>

Now restart apache.

/etc/init.d/apache2 restart

And you're done. Clean urls should work for you now.

For more information on this, see http://drupal.org/node/945860. To read about other ways to configure Apache and avoid the performance hit of using .htaccess, see http://drupal.org/node/43788.