Setting up a new Mac for Node.js and Drupal development
UPDATE: I am now of the opinion that you're probably better off installing homebrew with a prefix of somewhere inside your user directory, eg. ~/.homebrew/
. I mention this below as an alternative, but now this would be my primary recommendation. Some parts, however, such as configuring the Apple-included Apache installation, and the custom DNS resolvers, are system-wide changes, so you might not want to couple them to a particular user account. Perhaps consider brew install
ing a user-local copy of Apache, but use a system level installation of dnsmasq.
Original article text follows:
So you've got a fresh, clean Mountain Lion install and you need to get up and running for local development. Recently I spent a day doing just that, so I thought I'd write it all down, to save me from having to look all this stuff up again.
Install Xcode Command Line Tools
Available from the Apple Developer downloads area. You'll need an Apple ID.
This package includes llvm-gcc, which is a (mostly) compatible replacement for gcc. It will work for most homebrew formulas which build with gcc.
Install homebrew
homebrew can be conveniently installed with one line in the Terminal. As with all curl-to-sh style install scripts, you should read the script first to make sure it's not going to do anything bad. Don't say I didn't warn you :)
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
The most convenient approach to using homebrew is to make /usr/local
writable to admin group, if you don’t mind a (sort of) security risk. Bear in mind, /Applications
is writable by that group by default anyway, so unless you've locked that down also, this won't really make your system much more insecure than it already is.
sudo chmod -R g+w /usr/local
Unfortunately without doing this, homebrew doesn't work particularly well in its default install location. Alternatively install somewhere user-local like ~/homebrew
if you're really concerned about security and locking down user permissions on your local machine.
Install Node.js
Node in particular is easier to install from the nodejs.org installer package, not homebrew. Due to some past disagreement between the maintainers of npm and homebrew, the homebrew formula for node doesn’t properly install npm. The official installer, however, works pretty well.
To get npm install -g
working (without sudo) you may also want to change the global node_modules directory to have a group id of 'admin':
sudo chgrp -R admin /usr/local/lib/node_modules
You may also need to give g+w permissions to that directory tree, if you installed node after running the chmod command above. This comes with the same caveats as homebrew. If you're really security conscious, install node and npm somewhere in your user directory, rather than globally in /usr
.
Install Redis & MongoDB (optional)
brew install redis
redis-server
brew install mongodb
mongod
Install MySQL
brew install mysql
Then follow the instructions depending on whether you want MySQL to run as your user account or a different one, where data should be stored and whether you want to start the daemon manually or run at login.
Eg. to set up databases to run as your user account, with data in /usr/local/var/mysql
and running at login:
unset TMPDIR
mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp
To have launchd start mysql at login:
ln -sfv /usr/local/opt/mysql/*.plist ~/Library/LaunchAgents
Then to load mysql now:
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
Set up the root mysql account. Pick a better password than I have.
/usr/local/opt/mysql/bin/mysqladmin -u root password 123456
Install PHP 5.4 (optional)
PHP is not in the main homebrew packages, so you'll need to 'tap' some extra repos before you can install it.
brew tap homebrew/dupes
brew tap josegonzalez/homebrew-php
Update LoadModule directive in Apache config file to point to new PHP version
# /etc/apache2/httpd.conf
# Apple default:
# LoadModule php5_module libexec/apache2/libphp5.so
# This should be equivalent to $(brew --prefix php54)/libexec/apache2/libphp5.so
LoadModule php5_module /usr/local/opt/php54/libexec/apache2/libphp5.so
Add updated PHP version to the PATH in .bash_profile
# ~/.bash_profile
export PATH="$(brew --prefix php54)/bin:$PATH"
MySQL socket location & PHP PDO extension
When first running a PHP application which connects to MySQL, you may run in to errors relating to the socket through which PHP's PDO extension is attempting to connect to MySQL. This is because PDO is looking for the MySQL socket at /var/mysql/mysql.sock
, but it's probably at /tmp/mysql.sock
instead.
Some options you have include setting up a php.ini file:
sudo cp /etc/php.ini.default /etc/php.ini
sudo vi /etc/php.ini
and setting pdo_mysql.default_socket=/tmp/mysql.sock
therein. If you go for the php.ini approach it might also be worth setting display_errors = On
while you're there.
Or you could use a symbolic link to make PHP happy:
sudo mkdir /var/mysql
sudo ln -s /tmp/mysql.sock /var/mysql/mysql.sock
I'm not really sure which solution is best, but both seem to do the job.
Set up .dev TLD for local development using dnsmasq
No one likes having to go and edit your hosts file, or something similarly tedious, every single time they create a new local project. By setting up a special TLD and dynamic vhosts, we can avoid ever having to waste time with this stuff again.
brew install dnsmasq
mkdir -pv $(brew --prefix)/etc/
Configure dnsmasq
echo 'address=/.dev/127.0.0.1' > $(brew --prefix)/etc/dnsmasq.conf
Create LaunchDaemon so dnsmasq runs at startup
sudo cp -v $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons
sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
Set up a custom resolver to delegate resolution for .dev domains to dnsmasq
sudo mkdir -v /etc/resolver
sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/dev'
Set up dynamically configured mass virtual hosting in Apache
Ideally, all you should need to do to spool up a new site for development is create a directory under /srv/www
.
This Apache config should let you do just that.
Create /etc/apache2/other/mass-vhost.conf:
<Directory /srv/www>
Order Deny,Allow
Allow from all
AllowOverride All
</Directory>
NameVirtualHost *:80
<VirtualHost *:80>
# get the server name from the Host: header
UseCanonicalName Off
# include the server name in the filenames used to satisfy requests
VirtualDocumentRoot /srv/www/%1
</VirtualHost>
Create your sites directory
sudo mkdir -p /srv/www
sudo chown -R _www:_www /srv/www
sudo chmod -R g+w /srv/www
Add your user account to the _www group so you can write to /srv/www
sudo dseditgroup -o edit -a `whoami` -t user _www
Start Apache (and configure it to start automatically at startup)
sudo apachectl start
Install Drush
brew install drush
Set up a test Drupal site
Create a database in MySQL
cd /srv/www
drush dl drupal
mv drupal-* dtest
Create a Drupal settings.php file and fill it out with your database credentials.
In the site .htaccess file uncomment the directive:
# RewriteBase /
Navigate to http://dtest.dev/install.php Once installed, you should also be able to enable Clean URLs.
And you're done!