Apr 28 2014
Apr 28
Home Apache 2.4 Delete Default Site

Delete Default Site

Posted on April 28, 2014 duraturk Leave a comment

When I got my first VPS (from Linode) like 4 years ago, for heavy Drupal use, I read a lot of guides about setting up a LAMP stack on Ubuntu. At first most of those guides I read and followed were Drupal specific but later on I read a lot of non-drupal, LAMP stack related stuff as well.

In addition to the guides I read (and still reading), now I have 4 years of experience and knowledge that I learned by trial & error. Not to mention that I have a long System Admin (Windows only) and Database Admin (mostly Oracle) past. I still wouldn’t call myself a full-blown Linux System Admin but I believe I have come quite a long way since then.

Now I am thinking about the guides and wondering why none of the ones I read does not tell people to delete the default site configuration that comes enabled upon Apache installation. As if this is not enough, almost all of them relies on making changes on that default site config (Drupal or not).

99 times out of 100, you do not want/need a default site running on your server; which will service to any request that finds your server via IP or DNS; unless the request belongs to a website that you specifically configured. And I am sure you don’t want your apache to service a request, let’s say, http://imap.example.com unless you specifically configured a site for imap.example.com.

One of the first things I do is to delete that default website.
I can either delete the symlink…

cd /etc/apache2/sites-enabled/
rm 000-default.conf
service apache2 reload

or you can do it by disabling the site with “a2dissite” command. Some might say that this is the proper way to do it but actually they do the same thing; removes the symlink.

a2dissite 000-default.conf
service apache2 reload

As you have noticed that I did not actually delete the default site configuration file which resides in “/etc/apache2/sites-available/” I have only disabled that site. Who knows, I might need that file in the future (for reference purposes most likely).

Now the question pops in mind; the guides you follow tells you to make a change in that default site config file. Of course the changes will not have any effect since the default site is disabled. As for Drupal, it will ask you to change “AllowOverride None” to “AllowOverride All” in the below shown block.

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted

This is how you do it. Open your “apache2.conf” file, where your real defaults are set. Find the same block and make the same change there.

cd /etc/apache2/
vi apache2.conf
##  Make the changes  ##
service apache2 reload

This is on Ubuntu 14.04 …

Advertisements Tagged with: ,
Posted in Apache 2.4, Drupal, Ubuntu
Feb 01 2012
Feb 01

In this video we set up a LAMP stack web server for local development on an Ubuntu desktop (version 11.10). We will walk through installing and using tasksel to get the web server installed, then we'll add phpmyadmin to the mix. Once we have the server up and running, we'll look at where the web root is and how to add websites. Finally we wrap up with a quick look at how to start, stop, and restart our server when needed.

Dec 09 2011
Dec 09

Drupal can power any site from the lowliest blog to the highest-traffic corporate dot-com. Come learn about the high-end of the spectrum with this comparison of techniques for scaling your site to hundreds of thousands or millions of page views an hour. This Do it with Drupal session with Nate Haug will cover software that you need to make Drupal run at its best, as well as software that acts as a front-end cache (a.k.a Reverse-Proxy Cache) that you can put in-front of your site to offload the majority of the processing work. This talk will cover the following software and architectural concepts:

  • Configuring Apache and PHP
  • MySQL Configuration (with Master/Slave setups)
  • Using Memcache to reduce database load and speed up the site
  • Using Varnish to serve up anonymous content lightning fast
  • Hardware overview for high-availability setups
  • Considering nginx (instead of Apache) for high amounts of authenticated traffic
Mar 16 2011
Mar 16

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.]

Ubuntu Linux + DrupalDrupal requires some things, and likes some other things a lot. Here's how to configure the latest Ubuntu Linux to make Drupal happy.


  • 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 "[email protected]"

      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 "". 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.]        localhost.localdomain        localhost      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:


    3. Edit /etc/apache2/sites-available/default
      nano /etc/apache2/sites-available/default

      Edit as such:


      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


      for each of your sites on the server.

      nano /etc/apache2/sites-available/example1.com

           ServerAdmin [email protected]
           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

      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.


      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:


      …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;
    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
      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:


      [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]

      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
      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


  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

      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.


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

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.

Jan 06 2011
Jan 06

Congratulations to the Drupal community for getting version 7.0 released! This is a major mile stone and an excellent reason to celebrate!

If you want to give Drupal 7 a try without having to install anything, I've now updated my Drupal 7 appliances on SuSE Studio to the latest release. The appliance is based on openSUSE Linux 11.3 and is available in two variants:

  • A text-mode only appliance to which you connect using your local web browser via the network.
  • A GUI version that starts up the Firefox browser in a minimalistic GNOME desktop to perform the installation locally. Remote network access is available, too.
The database backend is MySQL 5.1, with the InnoDB plugin and strict mode enabled. phpMyAdmin has been added to support web-based administration of the MySQL server. You can access it via http://localhost/phpMyAdmin/. I also added drush, the Drupal command line shell and scripting interface and some additional packages (yast2-http-server, bind-utils, php5-ctype, patch). I also bumped up the appliance's version number to 7.0.0, to match the version number of Drupal included.

The appliance is available in various formats:

  • A live raw disk image, ready to be written to an USB stick or flash drive
  • A live ISO image, to be burned on a CD or used in a virtual machine
  • A hard disk image, to be dumped on a hard disk drive
  • Various virtual disk formats, e.g. OVF, VMWare/VirtualBox/KVM and Xen
Please see the installation instructions provided on the download pages for details on how to use the various image formats.

So congratulations to the Drupal developer community for reaching this goal and thanks to SuSE/Novell/Attachmate for providing the infrastructure for creating such appliances. I also would like to especially thank Richard Bos for the testing and many suggestions for improvement of these appliances!

Oct 15 2010
Oct 15

Apple OS X comes with Apache and PHP built-in but need some tweaking to work. It also does not come with MySQL. Because of this, many developers have chosen to use MacPorts, Homebrew, or MAMP to install new binaries for Apache, PHP, and MySQL. However, doing this means your system would have multiple copies of Apache and PHP on your machine, and could create conflicts depending on how your built-in tools are configured. This tutorial will show you how to get the built-in versions of Apache and PHP running with an easy to install version of MySQL.

Additionally, it will show how to set up and install Drush, and phpMyAdmin. Setting up a new website is as easy as editing a single text file and adding a line to your /etc/hosts file. All of our changes will avoid editing default configuration files, either those provided by Apple in OS X or from downloaded packages, so that future updates will not break our customizations.


  1. Apple uses what appears to be the FreeBSD "version" of Apache 2.2, and includes various sample files. One of the sample files is a virtual hosts file that we will copy to our ~/Sites folder for easy editing. Launch the terminal and get started:

    $ cp /etc/apache2/extra/httpd-vhosts.conf ~/Sites

  2. In order to prevent future major OS updates from breaking our configuration, we'll be editing as few existing files as possible. Luckily, by default, OS X's httpd.conf file (the main configuration file for Apache) includes all *.conf files in another folder, /etc/apache2/other:

    $ tail -1 /etc/apache2/httpd.conf
    Include /private/etc/apache2/other/*.conf

  3. We then create a symbolic link in /etc/apache2/other to our newly-copied httpd-vhosts.conf from our ~/Sites folder:

    $ sudo ln -s ~/Sites/httpd-vhosts.conf /etc/apache2/other

  4. The ~/Sites/httpd-vhosts.conf is now where we will add all new virtual hosts. We will place our site root folders in ~/Sites and define them in this file. But first, we need to make some changes (or, download this edited httpd-vhosts.conf file and change fname in /Users/fname to the appropriate path for your system). Begin by adding this text to the top of the file, which will enable the ~/Sites folder and subfolders to be accessed by Apache (again, replace /Users/fname with your appropriate path for home directory):

    # Ensure all of the VirtualHost directories are listed below

    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all

  5. Add these lines anywhere in the file to ensure that http://localhost still serves the default folder:

    # For localhost in the OS X default location

    ServerName localhost
    DocumentRoot /Library/WebServer/Documents

  6. We will cover setting up a Virtual Host later, so let's reload our Apache settings to activate our new configuration:

    $ sudo apachectl graceful

    Or, go to the Sharing Preference Pane and uncheck/[re]check the Web Sharing item to stop and start Apache.


  1. As of OS X 10.6.6, OS X ships with PHP 5.3.3, but it is not enabled in Apache by default. By looking at /etc/apache2/httpd.conf, you can see that the line to load in the PHP module is commented out:

    $ grep php /etc/apache2/httpd.conf
    #LoadModule php5_module libexec/apache2/libphp5.so

  2. Since we are trying to avoid editing default configuration files where possible, we can add this information, along with the configuration to allow *.php files to run, without the comment at the beginning of the line, in the same folder that we put the symlink for httpd-vhosts.conf:

    $ sudo sh -c "cat > /etc/apache2/other/php5-loadmodule.conf <<'EOF'
    LoadModule php5_module libexec/apache2/libphp5.so

  3. PHP on OS X does not come with a configuration file at php.ini and PHP runs on its defaults. There is, however, a sample file ready to be copied and edited. The lines below will copy the sample file to /etc/php.ini (optionally, download the edited file and insert at /etc/php.ini) and add some developer-friendly changes to your configuration.

    $ sudo cp









    .default /






    $ sudo sh



    "cat >> /etc/php.ini <<'EOF'

    ;; User customizations below

    ; Original - memory_limit = 128M
    memory_limit = 196M
    ; Original - post_max_size = 8M
    post_max_size = 200M
    ; Original - upload_max_filesize = 2M
    upload_max_filesize = 100M
    ; Original - default_socket_timeout = 60
    default_socket_timeout = 600
    ; Original - max_execution_time = 30
    max_execution_time = 300
    ; Original - max_input_time = 60
    max_input_time = 600
    ; Original - log_errors = off
    log_errors = on
    ; Original - display_errors = Off
    display_errors = on
    ; Original - display_startup_errors = Off
    display_startup_errors = on
    ; Original - error_reporting = E_ALL & ~E_DEPRECATED
    error_reporting = E_ALL & ~E_DEPRECATED & ~E_NOTICE

  4. OS X's PHP does ship with pear and pecl, but they are not in the $PATH, nor are there binaries to add or symlink to your path. The first two commands will perform a channel-update for pear and again for pecl, the second two will add an alias for each for your current session, and the last two will add the aliases permanently to your local environment (you may get PHP Notices that appear to be errors but they are simply notices. You can change error_reporting in php.ini to silence the Notices):

    $ sudo php /usr/lib/php/pearcmd.php channel-update pear.php.net
    $ sudo php /usr/lib/php/peclcmd.php channel-update pecl.php.net
    $ alias pear="php /usr/lib/php/pearcmd.php"
    $ alias pecl="php /usr/lib/php/peclcmd.php"
    $ cat >> ~/.bashrc <<'EOF'

    alias pear="php /usr/lib/php/pearcmd.php"
    alias pecl="php /usr/lib/php/peclcmd.php"

  5. We do a lot of Drupal development, and a commonly-added PHP PECL module for Drupal is uploadprogress. With the new alias we just set, adding it is easy. Build the PELC package, add it php.ini, and reload the PHP configuration into Apache:

    Note: PECL modules require a compiler such as gcc to build. Install Xcode to build PECL packages such as uploadprogress.

    $ pecl install uploadprogress

    $ sudo sh



    "cat >> /etc/php.ini <<'EOF'

    ; Enable PECL extension uploadprogress

    $ sudo apachectl graceful


MySQL is the only thing that doesn't not ship with OS X that is needed to run a "LAMP" website like Drupal or WordPress. MySQL/Sun/Oracle provides pre-built MySQL binaries for OS X that don't conflict with other system packages, and even provides a nice System Preferences pane for starting/stopping the process and a checkbox to start MySQL at boot.

  1. Go to the download site for OS X pre-built binaries at: http://dev.mysql.com/downloads/mysql/index.html#macosx-dmg and choose the most appropriate type for your system. For systems running Snow Leopard, choose Mac OS X ver. 10.6 (x86, 64-bit), DMG Archive (on the following screen, you can scroll down for the download links to avoid having to create a user and password).

  2. Open the downloaded disk image and begin by installing the mysql-5.1.51-osx10.6-x86_64.pkg file (or named similarly to the version number you downloaded):

  3. Once the Installer script is completed, install the Preference Pane by double-clicking on MySQL.prefPane. If you are not sure where to install the preference pane, choose "Install for this user only":


  4. The preference pane is now installed and you can check the box to have MySQL start on boot or start and stop it on demand with this button. To access this screen again, load System Preferences. Click "Start MySQL Server" now:

  5. The MySQL installer installed its files to /usr/local/mysql, and the binaries are in /usr/local/mysql/bin which is not in the $PATH of any user by default. Rather than edit the $PATH shell variable, we add symbolic links in /usr/local/bin (a location already in $PATH) to a few MySQL binaries. Add more or omit as desired. This is an optional step, but will make tasks like using Drush or performing a mysqldump in the command line much easier:

    $ cd /usr/local/bin
    $ ln -s /usr/local/mysql/bin/mysql
    $ ln -s /usr/local/mysql/bin/mysqladmin
    $ ln -s /usr/local/mysql/bin/mysqldump
    $ ln -s /usr/local/mysql/support-files/mysql.server

  6. Next we'll run mysql_secure_installation to set the root user's password and other setup-related tasks. This script ships with MySQL and only needs to be run once, and it should be run with sudo. As you run it, you can accept all other defaults after you set the root user's password:

    $ sudo /usr/local/mysql/bin/mysql_secure_installation

  7. If you were create a simple php file containing "phpinfo();" to view the PHP Information, you will see that Apple-built PHP looks for the MySQL socket at /var/mysql/mysql.sock:

    The problem is that the MySQL binary provided by Oracle puts the socket file in /tmp, which is the standard location on most systems. Other tutorials have recommended rebuilding PHP from source, or changing where PHP looks for the socket file via /etc/php.ini, or changing where MySQL places it when starting via /etc/my.cnf, but it is far easier and more fool-proof to create a symbolic link for /tmp/mysql.sock in the location OS X's PHP is looking for it. Since this keeps us from changing defaults, it ensures that a PHP update (via Apple) or a MySQL update (via Oracle) will not have an impact on functionality:

    $ sudo mkdir /var/mysql
    $ sudo chown _mysql:wheel /var/mysql
    $ sudo ln -s /tmp/mysql.sock /var/mysql

  8. After installing MySQL, several sample my.cnf files are created but none is placed in /etc/my.cnf, meaning that MySQL will always load in the default configuration. Since we will be using MySQL for local development, we will start with a "small" configuration file and make a few changes to increase the max_allowed_packet variable under [mysqld] and [mysqldump] (optionally, use the contents of this sample file in /etc/my.cnf). Later on, we can edit /etc/my.cnf to make other changes as desired:

    $ sudo cp /usr/local/mysql/support-files/my-small.cnf /etc/my.cnf
    $ sudo sed -i "" 's/max_allowed_packet = 16M/max_allowed_packet = 2G/g' /etc/my.cnf
    $ sudo sed -i "" "/\[mysqld\]/ a\\`echo -e '\n\r'`max_allowed_packet = 2G`echo -e '\n\r'`" /etc/my.cnf

  9. To load in these changes, go back to the MySQL System Preferences pane, and restart the server by pressing "Stop MySQL Server" followed by "Start MySQL Server." Or, you can do this on the command line (if you added this symlink as shown above):

    $ sudo mysql.server restart

    Shutting down MySQL
    ... SUCCESS!
    Starting MySQL
    ... SUCCESS!


At this point, the full "MAMP stack" (Macintosh OS X, Apache, MySQL, PHP) is ready, but adding phpMyAdmin will make administering your MySQL install easier.

  1. phpMyAdmin will complain that the PHP extension 'php-mcrypt' is not available. Since you will not likely be allowing anyone other than yourself to use phpMyAdmin, you could ignore it, but if you want to build the extension, it is possible to build it as a shared object instead of having to rebuild PHP from source. Follow Michael Gracie's guide here (for his Step 2, grab the PHP source that matches "$ php --version" on your system): http://michaelgracie.com/2009/09/23/plugging-mcrypt-into-php-on-mac-os-x-snow-leopard-10.6.1/ (or, if you prefer Homebrew: http://blog.rogeriopvl.com/archives/php-mcrypt-in-snow-leopard-with-homebrew/ . The following files will be added:
    • /usr/local/lib/libmcrypt
    • /usr/local/include/mcrypt.h
    • /usr/local/include/mutils/mcrypt.h
    • /usr/local/bin/libmcrypt-config
    • /usr/local/lib/libmcrypt.la
    • /usr/local/lib/libmcrypt.4.4.8.dylib
    • /usr/local/lib/libmcrypt.4.dylib
    • /usr/local/lib/libmcrypt.dylib
    • /usr/local/share/aclocal/libmcrypt.m4
    • /usr/local/man/man3/mcrypt.3
    • /usr/lib/php/extensions/no-debug-non-zts-20090626/mcrypt.so
  2. The following lines will install the latest phpMyAdmin to /Library/WebServer/Documents and set up config.inc.php. Afterwards, you will be able to access phpMyAdmin at http://localhost/phpMyAdmin:
  3. $ cd /Library/WebServer/Documents
    $ curl -s -L -O http://downloads.sourceforge.net/project/phpmyadmin/phpMyAdmin/`curl -s -L http://www.phpmyadmin.net/home_page/index.php | grep -m1 dlname |awk -F'Download ' '{print $2}'|cut -d "<" -f1`/phpMyAdmin-`curl -s -L http://www.phpmyadmin.net/home_page/index.php | grep -m1 dlname |awk -F'Download ' '{print $2}'|cut -d "<" -f1`-english.tar.gz
    $ tar zxpf `ls -1 phpMyAdmin*tar.gz|sort|tail -1`
    $ rm `ls -1 phpMyAdmin*tar.gz|sort|tail -1`
    $ mv `ls -d1 phpMyAdmin-*|sort|tail -1` phpMyAdmin
    $ cd phpMyAdmin
    $ cp config.sample.inc.php config.inc.php
    $ sed -i "" "s/blowfish_secret\'\] = \'/blowfish_secret\'\] = \'`cat /dev/urandom | strings | grep -o '[[:alnum:]]' | head -n 50 | tr -d '\n'`/" config.inc.php


Drush is a helpful tool that provides a "Drupal shell" to speed up your Drupal development.

  1. Run the following in the Terminal to get Drush 4.2 installed in /usr/local and add drush to the $PATH:

    $ svn co http://subversible.svn.beanstalkapp.com/modules/drush/tags/DRUPAL-7--4-2/ /usr/local/drush
    $ cd /tmp
    $ pear download Console_Table
    $ tar zxvf `ls Console_Table-*.tgz` `ls Console_Table-*.tgz | sed -e 's/\.[a-z]\{3\}$//'`/Table.php
    $ mv `ls Console_Table-*.tgz | sed -e 's/\.[a-z]\{3\}$//'`/Table.php /usr/local/drush/includes/table.inc
    $ rm -fr Console_Table-*
    $ ln -s /usr/local/drush/drush /usr/local/bin/drush

Virtual Hosts

Now that all of the components to run a website locally are in place, it only takes a few changes to ~/Sites/httpd-vhosts.conf to get a new local site up and running.

  1. Your website code should be in a directory in ~/Sites. For the purposes of this example, the webroot will be at ~/Sites/thewebsite.

  2. You need to choose a "domain name" for your local site that you will use to access it in your browser. For the example, we will use "myproject.local". The first thing you need to do is add a line to /etc/hosts to direct your "domain name" to your local system:

    $ sudo sh -c "cat >> /etc/hosts <<'EOF' myproject.local

  3. If you have been following the rest of this guide and used a copy of /etc/apache2/extra/httpd-vhosts.conf in ~/Sites/httpd-vhosts.conf, you can delete the first of the two example Virtual Hosts and edit the second one. You can also delete the ServerAdmin line as it is not necessary.

  4. Change the ServerName to myproject.local (or whatever you entered into /etc/hosts) so Apache will respond when you visit http://myproject.local in a browser.

  5. Change the DocumentRoot to the path of your webroot, which in this example is /Users/fname/Sites/thewebsite

  6. It's highly recommended to set a CustomLog and an ErrorLog for each virtual host, otherwise all logged output will be in the same file for all sites. Change the line starting with CustomLog from "dummy-host2.example.com-access_log" to "myproject.local-access_log", and for ErrorLog change "dummy-host2.example.com-error_log" to "myproject.local-error_log"

  7. Save the file and reload the Apache configuration as shown in Step 6 under the Apache section, and visit http://myproject.local in your browser.

Going forward, all you have to do to add a new website is duplicate and edit the to section underneath your existing configuration, make new edits, edit /etc/hosts again, and reload Apache.

Aug 26 2008
Aug 26

a while ago i posted some performance benchmarks for drupal running on a variety of servers in amazon's elastic compute cloud.

amazon have just released ebs, the final piece of technology that makes their ec2 platform really viable for running lamp stacks stuck as drupal.

ebs, the "elastic block store", provides sophisticated storage for your database instance, with features including:

  • high io throughput
  • data replication
  • large storage capacity
  • hot backups using snapshots
  • instance type portability e.g. quickly swapping your database hardware for a bigger machine.

amazon also have a great mysql on ebs tutorial on their developer connection.

let me know if you've given this a go. it looks like a great platform.

Apr 15 2008
Apr 15
recently i posted some encouraging performance benchmarks for drupal running on a variety of servers in amazon's elastic compute cloud. while the performance was encouraging, the suitability of this environment for running lamp stacks was not. ec2 had some fundamental issues including a lack of static ip addresses and no viable persistent storage mechanism.

amazon are quickly rectifying these problems, and recently announced elasic ip addresses; a "static" ip address that you own and can dynamically point at any of your instances.

today amazon indicated that persistent storage will soon be available. they claim that this storage will:

  • behave like raw, unformatted hard drives or block devices
  • be significantly more durable than the local disks within an amazon ec2 instance
  • support snapshots backed up to S3
  • support volumes ranging in size from 1GB to 1TB
  • allow the attachment of multiple volumes to a single instance
  • allow high throughput, low latency access from amazon ec2
  • support applications including relational databases, distributed file systems and hadoop processing clusters using amazon ec2

if this works as advertised, it will make ec2 a wonderful platform for your lamp application. amazon promise public availability of this service later this year.

Jan 30 2008
Jan 30

I'd never seen the reference outside of Sun before today, but there it was, in the conference program for DrupalCon Boston :


Describing the Site Building track at the conference, the program lists track topics, including, "Drupal and \*AMP, a systems levelDrupalCon Boston logo view".  The asterisk clearly denotes a substitution variable, which had previously been the constant "L", preceding the abbreviation for Apache-MySQL-PHP/Perl/Python.  This is a clear tip of the hat to Solaris.  The new acronym, presumably pronounced star amp, bestows equal opportunity status to Solaris and Linux within the Drupal community.

I expect there will be plenty of interest in Solaris and other Sun technologies at DrupalCon, which convenes March 3-6 at the Boston Convention & Expo Center - the news of Sun's intent to acquire MySQL did not go unnoticed, and high profile sites running on Solaris are turning up frequently.  I guess that's why my Inbox has been overflowing with correspondence from the Drupal community.

Sun is a Gold sponsor of DrupalCon Boston.  We'll be handing out Solaris Express DVD's and we're giving a Sun Fire T1000 server to the winner of the Drupal Showcase competition.  I'll be a panelist in the Performance Tuning session, and I'll also be presenting some Solaris deployment techniques and best practices similar to what I presented at a DrupalCon last September in Barcelona.  I'm hoping we'll also have a contingent from Project Caroline to let the community in on the next big thing in Web2.0 development platforms.  As if all that from Sun wasn't enough, rumor has it, MySQL Director of Technology, Brian Aker is going to keynote the conference.

Jan 28 2008
Jan 28
amazon's elastic compute cloud, "ec2", provides a flexible and scalable hosting option for applications. while ec2 is not inherently suited for running application stacks with relational databases such as lamp, it does provide many advantages over traditional hosting solutions.

in this article we get a sense of lamp performance on ec2 by running a series of benchmarks on the drupal cms system. these benchmarks establish read throughput numbers for logged-in and logged-out users, for each of amazon's hardware classes.

we also look at op-code caching, and gauge it's performance benefit in cpu-bound lamp deployments.

the elastic compute cloud

amazon uses xen based virtualization technology to implement ec2. the cloud makes provisioning a machine as easy as executing a simple script command. when you are through with the machine, you simply terminate it and pay only for the hours that you've used.

ec2 provides three types of virtual hardware that you can instantiate. these are summarized in the table below.

machine type hourly cost memory cpu units platform small Instance $0.10 1.7 GB 1 32-bit platform large Instance $0.40 7.5 GB 4 64-bit platform extra large Instance $0.80 15 GB 8 64-bit platform note: one compute unit provides the equivalent CPU capacity of a 1.0-1.2 GHz 2007 Opteron or 2007 Xeon processor.

target deployments

to keep things relatively simple, the target deployment for our load test is basic; the full lamp stack runs on a single server. this is step zero in the five deployment steps that i outlined in an open-source infrastructure for high-traffic drupal sites.

our benchmark

our benchmark consists of a base drupal install, with 5,000 users and 50,000 nodes of content-type "page". nodes are an even distribution of 3 sizes, 1K, 3K and 22K. the total database size is 500Mb.

during the test, 10 threads read nodes continually over a 5 minute period. 5 threads operate logged-in. the other 5 threads operate anonymously (logged-out). each thread reads nodes randomly from the pool of 50,000 available.

this test is a "maximum" throughput test. it creates enough load to utilize all of the critical server resource (cpu in this case). the throughput and response times are measured at that load. tests to measure performance under varying load conditions would also be very interesting, but are outside the scope of this article.

the tests are designed to benchmark the lamp stack, rather than weighting it towards apache. consequently they do not load external resources. that is, external images, css javascript files etc are not loaded, only the initial text/html page. this effectively simulates drupal running with an external content server or cdn.

the benchmark runs in apache jmeter. jmeter runs on a dedicated small-instance on ec2.

benchmarking is done with op-code caching on and off. since our tests are cpu bound, op-code caching makes a significant difference to php's cpu consumption.

our testing environment

the tests use a debian etch xen instance, running on ec2. this instance is installed with:
  • MySQL: 5.0.32
  • PHP: 5.2.0-8
  • Apache: 2.2.3
  • APC: 3.0.16
  • Debian Etch
  • Linux kernel: 2.6.16-xenU

the tests use a default drupal installation. drupal's caching mode is set to "normal". no performance tuning was done on apache, mysql or php.

the results

all the tests ran without error. each of the tests resulted in the server running at close to 100% cpu capacity. the tests typically reached steady state within 30s. throughputs gained via jmeter were sanity checked for accuracy against the http and mysql logs. the raw results of the tests are shown in the table below. instance apc? logged-in throughput logged-in response logged-out throughput logged-out response small off 194 1.50 664 0.45 large off 639 0.46 2,703 0.11 xlarge off 1,360 0.20 3,741 0.08 small on 905 0.30 3,838 0.07 large on 3,106 0.10 8,033 0.04 xlarge on 4,653 0.06 12,548 0.02

note: response times are in seconds, throughputs are in pages per minute

the results - throughput

the throughput of the system was significantly higher for the larger instance types. throughput for the logged-in threads was consistently 3x lower than the logged-out threads. this is almost certainly due to the drupal cache (set to "normal").

throughput was also increased by about 4x with the use of the apc op-code cache.

the results - response times

the average response times were good in all the tests. the slowest tests yielded average times of 1.5s. again, response times where significantly better on the better hardware and reduced further by the use of apc.


drupal systems perform very well on amazon ec2, even with a simple single machine deployment. the larger hardware types perform significantly better, producing up to 12,500 pages per minute. this could be increased significantly by clustering as outlined here.

the apc op-code cache increases performance by a factor of roughly 4x.

these results are directly applicable to other cpu bound lamp application stacks. more consideration should be given to applications bound on other external resources, such as database queries. for example, in a database bound system, drupal's built-in cache would improve performance more significantly, creating a bigger divergence in logged-out vs logged-in throughput and response times.

although performance is good on ec2, i'm not recommending that you rush out and deploy your lamp application there. there are significant challenges in doing so and ec2 is still in beta at the time of writing (Jan 08). it's not for the faint-of-heart. i'll follow up in a later blog with more details on recommended configurations.

tech blog

if you found this article useful, and you are interested in other articles on linux, drupal, scaling, performance and LAMP applications, consider subscribing to my technical blog.


About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web