Automatic Apache vhosts

26th March 2012

One thing that I've wanted to implement for a while now is automatic vhosts on my dev box. The idea is that I want to drop a folder into a directory and have it automatically turned into a vhost for me accessible at http://foldername.dev. It turns out that this isn't nearly as hard as expected which is usually the case with things that I've been putting off!

This is how to do it.

Apache configuration

The Apache magic is in an extension called mod_vhost_alias which you may need to enable in your httpd.conf file.

You can then set up the VirtualHost wherever you keep such things. On a stock OS X, the extras/httpd-vhosts.conf file is used.

Add the following to the bottom:

<Virtualhost *:80>
    VirtualDocumentRoot "/www/dev/%1/public"
    ServerName vhosts.dev
    ServerAlias *.dev
    UseCanonicalName Off
    LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon
    ErrorLog "/www/dev/vhosts-error_log"
    <Directory "/www/dev/*">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</Virtualhost>

In the VirtualHost configuration, I have used the ServerAlias and VirtualDocumentRoot directives to map http://foldername.dev to the directory /www/dev/foldername/public. Hence, any folder that I place in /www/dev will have its own virtual host. Alter these appropriately for your set-up.

Don't forget to restart Apache.

Unfortunately, the computer hasn't a clue how to handle http://foldername.dev and the obvious solution is to run a local DNS server. Another solution is to use a PAC file.

DNS server configuration

This is easy enough with dnsmasq. On OS X, use Homebrew to install like this: brew install dnsmasq. On Linux, use your package manager; on Windows, you're own your own!

Note that on OS X, you should set it to start up automatically using launchd as noted in the instructions after installation. You also need to copy the configuration file to /etc using: cp /usr/local/Cellar/dnsmasq/2.57/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf (or whatever the latest version number is). on Linux, I would guess that your package manager provides a dnsmasq.conf file in /etc or /etc/dnsmasq.

Next, edit dnsmasq.conf file and added the following lines to the bottom:

listen-address=127.0.0.1
address=/.dev/127.0.0.1

Add the name server to your network configuration

On OS X, Go to System Preferences -> Network -> {Wifi or Ethernet} -> Advanced… -> DNS and click on + button at the bottom of the left hand panel and add 127.0.0.1 to the list of DNS servers. Drag 127.0.0.1 at the top of the list.

On Linux, you should use the appropriate GUI tools for your distribution or potentially edit etc/dhcp/dhclient.conf and uncomment the domain-name-servers 127.0.0.1; on line 20 (on Ubuntu).

Restart dnsmasq and you should now be able to execute host test.dev on the command line and see 127.0.0.1 as the resultant address.

Alternative to DNS server: PAC file

Since publishing this article, Chris Morell pointed out that you can also use PAC files rather than install a DNS server. Details are on his blog post.

Check it works

Create a directory called test in your dev directory. Within test, create public/index.php and within index.php add some code to prove it works. e.g. < ;?php echo "Hello World"; ?>;

If you navigate to http://test.dev, you should see "Hello World" displayed.

Caveats

A couple of caveats:

  • DOCUMENT_ROOT is not /www/dev/test as you'd expect. Instead it is the global document root. See this gist for a neat way to solve this using a prepend file.
  • If you use mod_rewrite, then you'll need a RewriteBase / in your .htaccess file. Alternatively, you can change the Directory section of your vhost to do the rewriting for you if all your projects are alike. Something like this should work:
        <Directory "/www/dev/*">
            Options Indexes FollowSymLinks MultiViews
            AllowOverride None
            Order allow,deny
            Allow from all
    
            RewriteEngine On
            RewriteBase /
            RewriteCond %{REQUEST_FILENAME} -s [OR]
            RewriteCond %{REQUEST_FILENAME} -l [OR]
            RewriteCond %{REQUEST_FILENAME} -d
            RewriteRule ^.*$ - [NC,L]
            RewriteRule ^.*$ index.php [NC,L]
        </Directory>
    

All done

That's it. You can now create as many projects as you like without having to worry about setting up new virtual hosts or modifying you hosts file!

OS X Tips and Tricks

20th March 2012

It's been around 18 months since I wrote up some notes about OS X, so clearly it's time for an updated article.

This article is intended to give a quick and easy introduction to some key things that I think you should know when you move to using OS X.

Basics

  • There's one menu bar for all application
  • Closing the last window doesn't exit the application. Use cmd+q or the Quit menu item on the "application name" menu.
  • System Preferences is available via the Apple () menu.
  • Finder is the name of the file manager.
  • Preview is the name of the PDF and image viewer. It's more powerful than it looks.
  • Turn on View->Show Path Bar in Finder.
  • Browsing Mac 101 if you're new to Mac can be helpful.

Launchpad
You applications are stored in /Applications. The easiest way to get to them is via Launchpad. If you've used an iPhone then it will look familiar!

App Store
Get your software from the App Store if you can. It's easier than dealing with license keys and will integrate with Mountain Lion's notification centre.

Backup
Get a cheap USB external hard drive and use Time Machine. There are no excuses.

Zoom
The green button at the top left of a window is called Zoom, not Maximise for a reason! It doesn't do the same thing. OS X has "full screen mode" which is accessed by pressing the set diagonal arrows in the top right of a window.

Force quit
It's rare for an app to hang, but it does happen. If you need to force an application to quit, hold down ctrl and the alt key and then click on the app's icon in the Dock. select "Force quit" from the context menu.

FileVault
If your Mac is less than 2 years old, enable FileVault within System Preferences -> Security & Privacy -> FileVault. Also, set your computer up so that a password is required to login on start up and from sleep. It's worth it for the peace of mind if your laptop ever gets stolen.

British English dictionary
System Preferences -> Language & Text -> Language. Click "Edit List…" and find "British English" in the list and select it and press OK. Drag to top of list if not already there.

The £ symbol on a UK keyboard
alt+3 gives you a £! Just remember that Americans called the # symbol "pound"…

The file system: HFS+
HFS+ is OS X's filesystem and is case preserving, and is not case sensitive. Be aware of this at all times, or create a separate "HFS+ (case-sensitive)" partition using Disk Utility. Note that your main partition should be standard HFS+.

Keyboard access
System Preferences -> Keyboard -> Keyboard shortcuts. At the bottom, select "All controls". You can now use tab to move between buttons in a dialog box and press the space bar to select a tabbed-to button (blue focus outline).

Keyboard shortcuts

  • The cmd (command) key has the symbol ⌘ is used where Windows/Linux use the control key.
  • Option is another word for the alt key and has the ⌥ symbol
  • On the UK keyboard layout, the hash (#) character is found via option+3.
  • Cmd+tab switches applications; Cmd+` (backtick) switches windows within an application.
  • Cmd+space opens system wide search (called Spotlight)
  • Shift+Cmd+[ and Shift+Cmd+] usually switch tabs within a window.
  • Cmd+t will open a new tab in apps that have tabs.
  • Moving the caret:
    • left/right: move caret one character
    • alt+left/alt+right: move caret one word
    • cmd+left/cmd+right: move caret to start/end of the line
    • cmd+up/cmd+down: move caret to start/end of the document
    • The ↖ and ↘ arrows move the screen to the top and bottom of the document, but do not move the caret!
  • Cmd+g is find next
  • Cmd+r to refresh a web page as F5 doesn't work in Safari
  • Finder shortcuts:
    • The return key renames a file, not opens it!
    • cmd+down to open the selected file
    • cmd+up to go up a directory
    • shift+cmd+g to go to any specific directory. Useful to get to /usr/local/. Also works in any open/save dialog within an application.
  • Within a sheet:
    • Return key to select default option (filled in blue)
    • Escape key to cancel
    • cmd+delete to "Don't Save" in a save sheet
  • You can create (or edit) your own keyboard shortcuts for any application's menu item using System Preferences. This is really really good!

iPhoto opening on connection of iPhone

If you need to stop iPhoto opening every time you connect a camera or a phone, open Image Capture and select the camera in the list and then look at the panel in the bottom left.

Screenshots

  • Shift+cmd+3 for the whole screen.
  • Shift+cmd+4 and draw a rectangle with the mouse for an arbitrary area of the screen
  • Shift+cmd+4 then space then click on the window to get an PNG of that window.
  • Consider TinyGrab or Skitch if you want to share them
  • Terminal

    This is the command line application for OS X. Underneath, you have BSD, so it's works properly! Most common cli apps that you expect to be here are, such as, ls, du, df, curl, svn, etc. For anything else, use Homebrew.

    • "open ." will open a finder window in the current directory
    • Open Terminal Here is a useful script for Finder. Store in ~/bin and drag it onto your Finder toolbar.
    • My article on changing the Terminal's colours is useful.
    • Cmd+t for tabs in a Terminal window.
    • Cmd+k to clear the buffer.

    GCC / development
    Install the Apple Command Line Tools for Xcode. An Apple Id is required, but you don't have to pay for them. If you want to develop Cocoa applications, then get Xcode from the App Store.

    Unix utilities
    Install Homebrew.

    PHP
    Apple supply PHP 5.3.x with OS X 10.7 so you may as well use it. I wrote it up here: http://akrabat.com/phposx.

    Alternatively:

    • Liip have provided http://php-osx.liip.ch/ which is a one line binary PHP install for OS X.
    • ZendServer CE is a simple install and is regularly updated
    • You could always use home brew.

    Applications

    This is just an unsorted list of useful apps!

    I hope this is helpful!

    OS X Tips and Tricks for Snow Leopard

    4th October 2010

    Following some discussions with friends who've recently started using OS X, I thought I'd note down some tips and tricks that I've learnt since I moved to Mac. This is in no particular order as it's taken from IRC logs of conversations I've had :)

    Basics

    • There's one menu bar for all application
    • Closing the last window doesn't exit the application. Use cmd+q or the Quit menu item on the "application name" menu.
    • System Preferences is available via the Apple () menu.
    • Finder is the name of the file manager.
    • Preview is the name of the PDF and image viewer. It's more powerful than it looks.
    • Turn on View->Show Path Bar in Finder.
    • Browsing Mac 101 if you're new to Mac can be helpful.

    Backup

    Get a cheap USB external hard drive and use Time Machine. There are no excuses.

    PHP

    Apple supply PHP 5.3.x with OS X 10.6 so you may as well use it. I wrote it up here: http://akrabat.com/phposx. Another alternative is ZendServer CE which is also regularly updated.

    HFS+

    HFS+ is OS X's filesystem and is case preserving, and is not case sensitive. Be aware of this at all times, or create an "HFS+ (case-sensitive)" partition using Disk Utility.

    Keyboard shortcuts

    • The cmd (command) key has the symbol ⌘ is used where Windows/Linux use the control key.
    • Option is another word for the alt key and has the ⌥ symbol
    • On the UK keyboard layout, the hash (#) character is found via option+3.
    • Cmd+tab switches applications; Cmd+` (backtick) switches windows within an application.
    • Shift+Cmd+[ and Shift+Cmd+] usually switch tabs within a window.
    • Moving the caret:
      • left/right: move caret one character
      • alt+left/alt+right: move caret one word
      • cmd+left/cmd+right: move caret to start/end of the line
      • cmd+up/cmd+down: move caret to start/end of the document
      • The ↖ and ↘ arrows move the screen to the top and bottom of the document, but do not move the caret!
    • Cmd+g is find next
    • Cmd+r to refresh a web page as F5 doesn't work in Safari
    • Finder shortcuts:
      • The return key renames a file, not opens it!
      • cmd+down to open the selected file
      • cmd+up to go up a directory
      • shift+cmd+g to go to any specific directory. Useful to get to /usr/local/. Also works in any open/save dialog within an application.
    • You can create (or edit) your own keyboard shortcuts for any application's menu item using System Preferences.

    Screenshots

  • Shift+cmd+3 for the whole screen.
  • Shift+cmd+4 and draw a rectangle with the mouse for an arbitrary area of the screen
  • Shift+cmd+4 then space then click on the window to get an PNG of that window.
  • Terminal

    This is the command line application for OS X. Underneath, you have BSD, so it's works properly! Most common cli apps that you expect to be here are, such as, ls, du, df, curl, svn, etc. For anything else, use Homebrew.

    • "open ." will open a finder window in the current directory
    • Open Terminal Here is a useful script for Finder. Store in ~/bin and drag it onto your Finder toolbar.
    • My article on changing the Terminal's colours is useful.
    • Cmd+t for tabs in a Terminal window.
    • Cmd+k to clear the buffer.

    Applications

    • TextWrangler - it's a good free text editor that handles editing files owned by root really elegantly. Install the command line tools and then you can do edit /etc/php.ini.
    • MacVim.
    • Adium for IM.
    • Hibari or Twitterrific for Twitter.
    • Cyberduck for FTP. Though spending the $34 for Transmit is worth the cash if you do a lot of FTP.
    • NetNewsWire for RSS - integrates with Google Reader.
    • Colloquy for IRC.
    • MacFUSE to mount SSH and other 3rd parth files systems into OS X's native file handling. See also ExpanDrive also
    • Handbrake for converting DVDs and other video converting requirements.
    • OnmiDiskSweeper for a pretty version of "du".
    • Omni Graffle (not cheap!) is a very good diagramming tool.
    • If you tend to keep lots of small files with text notes in them, then look at Notational Velocity.
    • VMWare Fusion or Parallels Desktop if you need Windows/Linux VMs.
    • MarsEdit to write blog posts.
    • Acorn for image editing if you don't need or want Photoshop.
    • TinyGrab for screenshot sharing.
    • Xcode for gcc, make, and other dev tools. This also includes File Merge and the cli tool opendiff, for viewing diff/patch files.
    • MercuryMover for keyboard control of window positioning/sizing.

     

    That's all that comes to mind. Feel free to add more in the comments and if I come across anything else, I'll update this article :)

     

    Changing OS X Terminal colours when ssh'ing into a server

    2nd October 2009

    I recently discovered that iTerm has bookmarks so you can set up a bookmark to ssh into a server and change the colours of the window. This makes it easy to remember which terminal window is for which server.

    Thinking about it, I wondered if you could change the colours of the standard OS X Terminal via AppleScript. Inpired by Red Sweater's Random Color Terminal post, I wrote some code to automatically change the Terminal colour whenever I ssh into a known server.

    As I know PHP and PHP is installed on OS X, I used that :)

    The key to controlling AppleScript via PHP is the osascript command line application. The code I need specifically is:

    
    system("osascript -e 'tell application \"Terminal\"
                set targetWindow to window 1
                set background color of targetWindow to {" $bgColour "}
                set cursor color of targetWindow to {" $fgColour "}
                set normal text color of targetWindow to {" $fgColour "}
                set bold text color of targetWindow to {" $fgColour "}
            end tell' ");
    
    

    where $bgColour and $fgColour are comma separated strings containing three numbers between 0 and 65535 as AppleScript colours are 16 bit.

    We start by getting a command line solution where we can type:
    termcolour.php white
    or
    termcolour.php 00ff00
    or
    termcolour.php 255 0 0

    and have the background colour of the Terminal change to the colour we have asked for.

    TerminalColour class

    Firstly we need a class that can change the colour of the Terminal window for us and also translate colours from 8bit RGB to 16bit RGB. As it is also useful to be able to specify colours by name, eg. "white", we'll add a lookup system too. I store this in /usr/local/bin.

    This class is quite long, so this is a snippet:

    <?php
    class TerminalColour
    {
        protected $_colour = array('255','255','255');
        
        /**
         * List of colours
         */
        protected $_colours = array(
            'white' => 'ffffff',
            'black' => '000000',
            // etc
        );
        
    
        /**
         * Set the colour of the topmost Terminal window using AppleScript
         *
         * $bgColour may be either an array of red, green, blue (8 bit) or a 
         * hex string or a string that matches an entry in the _colours lookup 
         * list.
         *
         * If $fgColour is null, then automatically use either black or
         * white based on brightness of $bgColour.
         *
         * @param array|string $bgColour
         * @param array|string $fgColour
         * @return array
         */
        function setTerminalColour($bgColour=null$fgColour=null) 
        {
            if(!is_null($bgColour)) {
                $this->setColour($bgColour);
            }
            $bgColour $this->getColour();
            
            
            // convert from 8 bit colour numbers to 16 bit ones
            $bgColour $this->convertTo16bit($bgColour);
                
            if($fgColour === null) {
                $fgColour $this->getFgColour($bgColour);
            } else {
            }
            
            $bgColour implode(','$bgColour);
            $fgColour implode(','$fgColour);
        
            system("osascript -e 'tell application \"Terminal\"
                set targetWindow to window 1
                set background color of targetWindow to {" $bgColour "}
                set cursor color of targetWindow to {" $fgColour "}
                set normal text color of targetWindow to {" $fgColour "}
                set bold text color of targetWindow to {" $fgColour "}
            end tell' ");
        }
    }
    
    

    As you can see, there's a variety of helper methods that I've not show here. setColour() is the where we map from the types of input that the user will provide to an array. Other that that, it's fairly self-explanatory.

    Change colour from the command line

    Now we need a script that uses our class. termcolours.php, that I can execute from the command line to change any given Terminal window to a new background colour.

    termcolour.php is stored in /usr/local/bin and has execute permissions set using chmod a+x termcolour.php from the command line:

    #!/usr/bin/php
    <?php
    include dirname(__FILE__) . '/TerminalColour.php';
    
    process($argc$argv);
    exit;
    
    function process($argc$argv)
    {
        if($argc == 1) {
            echo <<<EOT
    TerminalColour: Set the background colour of a Terminal.app window 
    USAGE: 
        1. termcolour.php {r} {g} {b} 
            ({r}, {g}, {b} are between 0 and 255)
        2. termcolour.php {hexvalue}
            ({hexvalue} assumed to be from 000 to fff or 00000 to ffffff)
    
    EOT;
            exit;
        }
        
        $tc = new TerminalColour();
        if($argc == 4) {
            // called with three arguments - treat as rgb values (0-255)
            array_shift($argv); // remove name of script
            $tc->setTerminalColour($argv);
        }
        
        if($argc == 2) {
            // called with one argument - either a lookup or a hex value
            $tc->setTerminalColour($argv[1]);
        }
    }
    
    

    Again, not complicated. we check number of arguments to the script and if there are none, we display a help message. If there are exactly 1 or 3, then we call TerminalColour::setTerminalColour() appropriately.

    Hooking into SSH

    Lastly we hook into ssh and change the colour based on the server name.

    To do this, I've used a simple shell script and modified termcolours.php to add some additional colour look up entries.

    /usr/local/bin/sshcolours.sh:
    /usr/local/bin/termcolour.php $@
    /usr/bin/ssh $@
    /usr/local/bin/termcolour.php white

    termcolour.php

    
    //...
        
        $tc = new TerminalColour();
    
        // add colours for servers
        $colourLookup $tc->getLookupColours();
        $serverColours = array(
            'server1' => $colourLookup['darkblue'],
            'server2' => $colourLookup['red'],
            'server3' => 'C4DFC3',
        );
        $tc->addToLookupColours($serverColours);
    
        if($argc == 4) {
    //...
    
    

    (not a large change!)

    finally, we add an alias to ~/.bash_profile:

    
    alias s=sshcolours.sh
    
    

    That's it! I can now type:

    	s server1
    

    and Terminal's background colour turns blue and I'm ssh'd into server 1.

    Sometimes I just type termcolour.php darkred to remind myself that this terminal window is doing something long-running and not to accidentally close it...

    This is a zip file of the relevant files.

    Uninstalling MySQL on Mac OS X Leopard

    11th September 2008

    To uninstall MySQL and completely remove it (including all databases) from your Mac do the following:

    • Use mysqldump to backup your databases to text files!
    • Stop the database server
    • sudo rm /usr/local/mysql
    • sudo rm -rf /usr/local/mysql*
    • sudo rm -rf /Library/StartupItems/MySQLCOM
    • sudo rm -rf /Library/PreferencePanes/My*
    • edit /etc/hostconfig and remove the line MYSQLCOM=-YES-
    • rm -rf ~/Library/PreferencePanes/My*
    • sudo rm -rf /Library/Receipts/mysql*
    • sudo rm -rf /Library/Receipts/MySQL*
    • sudo rm -rf /private/var/db/receipts/*mysql*

    The last three lines are particularly important as otherwise, you can't install an older version of MySQL even though you think that you've completely deleted the newer version!