nginx / MariaDB / PHP / Aegir on Mac OS X with optional Drush 5 (works on Mountain Lion!)

Our original post on this topic has become a little outdated, and with Mountain Lion just around the corner here is an updated version that works on Mountain Lion and lets you elect to use Drush 5 if you want!
Step 1: Xcode and HomebrewXCode is required for Homebrew to compile dnsmasq, nginx, mariadb and php.
- Download and install Xcode using the Mac App Store with the link above
(it's free, but will take a while to download if your Internet connection is slow) - Once the download has finished launch Xcode and open it's preferences, goto Downloads tab and click Install on Command Line Tools.
- Follow the installation instructions for Homebrew, which most likley tell you to run this command in your terminal
$ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
- Let everyone know where Xcode is by entering this in your terminal
$ sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
- Install X11: Visit http://xquartz.macosforge.org/trac/wiki and download and install version 2.7.2+.
- You will need to fix the symlink it makes
$ sudo ln -s /opt/X11 /usr/X11
- Reinstall your brews
$ brew list
- Ensure /usr/local/bin occurs before /usr/bin and add /usr/local/sbin is added to your path, If you are using zsh, update .zshrc instead
$ nano ~/.bash_profile or $ nano ~/.zshrc
- Paste the following into editor then Ctrl+X and Y to save
export PATH=~/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin:/usr/local/git/bin:/opt/local/bin
- First test if you are able to email yourself, substituting with your own email address
$ date | mail -s test you@youremail.com
- If you are on Mountain Lion you need to create and set the permissions for these directories first (for DP4 at least)
$ sudo mkdir /Library/Server /Library/Server/Mail /Library/Server/Mail/Data /Library/Server/Mail/Data/spool /Library/Server/Mail/Data/spool/maildrop $ sudo chown _postfix:_postdrop /Library/Server/Mail/Data/spool/maildrop $ sudo chmod 777 /Library/Server/Mail/Data/spool/maildrop
- I chose to set up gmail as my email relay (this may not be required for you though)
http://realityloop.com/blog/2011/06/05/os-x-ditching-mamp-pro-part-2-gmail-email-relay - Mountain Lion appears to have a few bugs around this at the moment, I have to launch postfix on reboot
$ sudo postfix start
Run the following commands from terminal
- Ensure that you don't already have gzip installed via homebrew:
$ brew uninstall gzip
- Add hombrew dupes:
$ brew tap homebrew/dupes
- Reinstall gzip via homebrew
$ brew install homebrew/dupes/gzip
- Install dnsmasq via homebrew
$ brew install dnsmasq
- Copy and edit the default conf example
$ mkdir /usr/local/etc $ cp $(brew --prefix dnsmasq)/dnsmasq.conf.example /usr/local/etc/dnsmasq.conf $ nano /usr/local/etc/dnsmasq.conf
- Update the following values as shown
resolv-file=/etc/resolv.dnsmasq.conf address=/.ld/127.0.0.1 listen-address=127.0.0.1
- Set up downstream DNS resolver
$ sudo nano /etc/resolv.dnsmasq.conf
- Paste the following and save using CTRL + X then Y
# OpenDNS IPv6: nameserver 2620:0:ccd::2 nameserver 2620:0:ccc::2 # Google IPv6: nameserver 2001:4860:4860::8888 nameserver 2001:4860:4860::8844 # OpenDNS: nameserver 208.67.222.222 nameserver 208.67.220.220 # Google: nameserver 8.8.8.8 nameserver 8.8.4.4
- Copy the launch daemon so dnsmasq runs on startup, and launch it now
$ sudo cp $(brew --prefix dnsmasq)/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons $ sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist
- Set hostname as it's required for sane default in aegir setup, we chose rl.ld for Realityloop Local Development you can use something else instead of rl but it needs to end in .ld
$ sudo scutil --set HostName rl.ld
- Open your System Preferences, then click on Network, then for each of your interfaces (Wi-Fi & Ethernet), click on Advanced, click on DNS and finally click on the + symbol at the bottom of the left hand-side panel and set 127.0.0.1 as your only DNS Server
nginx (pronounced “engine-x”) is a Web server and a reverse proxy server for HTTP, SMTP, POP3 and IMAP protocols, with a strong focus on high concurrency, performance and low memory usage.
- Unless this is a fresh install of OS X you need to ensure Apache doesn't load on startup
$ sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
- We can add some 3rd party extensions here as well (this list item is optional, if you don't want these extensions just skip to the next list item)
Now one giant line of sed regex that will edit the Homebrew formula for nginx to add the additional compile options that we need. Make sure it all gets entered as one line.
$ curl -s -L -o /tmp/nginx-upload-progress.tar.gz https://github.com/masterzen/nginx-upload-progress-module/tarball/v0.9.0 && mkdir /tmp/nginx-upload-progress && tar zxpf /tmp/nginx-upload-progress.tar.gz --strip-components 1 -C /tmp/nginx-upload-progress && rm /tmp/nginx-upload-progress.tar.gz $ curl -s -L -o /tmp/nginx-fair.tar.gz http://github.com/gnosek/nginx-upstream-fair/tarball/master && mkdir /tmp/nginx-fair && tar zxpf /tmp/nginx-fair.tar.gz --strip-components 1 -C /tmp/nginx-fair && rm /tmp/nginx-fair.tar.gz
Now we'll install Nginx with our new build options and extensions and start it.$ sed -i '-default' 's/\([[:space:]]*\['\''--\)\(with-webdav\)\('\'',[[:space:]]*"\)\(Compile with support for WebDAV module\)\("\]\)/\1\2\3\4\5,%\1with-realip\3Compile with support for RealIP module\5,%\1with-gzip_static\3Compile with support for Gzip Static module\5,%\1with-uploadprogress\3Compile with support for Upload Progress module\5,%\1with-fair\3Compile with support for Fair module\5,%\1with-mp4\3Compile with support for MP4 module\5,%\1with-flv\3Compile with support for FLV module\5,%\1with-stub_status\3Compile with support for Stub Status module\5/; s/\([[:space:]]* args << "--\)\(with-http_dav_module\)\(" if ARGV.include? '\''--with-\)\(webdav\)\('\''.*\)/\1\2\3\4\5%\1with-http_realip_module\3realip\5%\1with-http_gzip_static_module\3gzip_static\5%\1add-module=\/tmp\/nginx-upload-progress\3uploadprogress\5%\1add-module=\/tmp\/nginx-fair\3fair\5%\1with-http_mp4_module\3mp4\5%\1with-http_flv_module\3flv\5%\1with-http_stub_status_module\3stub_status\5/; y/%/\n/' $(brew --prefix)/Library/Formula/nginx.rb
$ brew install nginx --with-realip --with-gzip_static --with-mp4 --with-flv --with-stub_status --with-uploadprogress --with-fair $ [ $? -eq 0 ] && rm -rf /tmp/nginx-upload-progress /tmp/nginx-fair $ mkdir -vp $(brew --prefix nginx)/var/{microcache,log,run} - If you didn't use the above to install extra nginx extensions run this, otherwise skip this command
$ brew install nginx
- Once nginx is compiled, backup the default nginx config
$ mv /usr/local/etc/nginx/nginx.conf /usr/local/etc/nginx/nginx.conf.bak
- Download our config as follows
$ curl http://realityloop.com/sites/realityloop.com/files/uploads/nginx.conf_.txt > /usr/local/etc/nginx/nginx.conf
- Set your username in the downloaded config file
$ sed -i -e 's/\[username\]/'`whoami`'/' /usr/local/etc/nginx/nginx.conf
- Make nginx log files visible in Console app
$ sudo mkdir /var/log/nginx
- Create the following directorty to stop “"/var/lib/nginx/speed" failed (2: No such file or directory)” error
$ sudo mkdir /var/lib/nginx
MariaDB is a community-developed branch of the MySQL database, the impetus being the community maintenance of its free status under GPL, as opposed to any uncertainty of MySQL license status under its current ownership by Oracle.
The intent also being to maintain high fidelity with MySQL, ensuring a "drop-in" replacement capability with library binary equivalency and exacting matching with MySQL APIs and commands. It includes the XtraDB storage engine as a replacement for InnoDB.
- Still in the ‘Terminal app’, type the following command
$ brew install mariadb --use-llvm --env=std
- Once compilation has finished unset TMPDIR
unset TMPDIR
- Then mysql_install_db
$ mysql_install_db --user=`whoami` --basedir="$(brew --prefix mariadb)" --datadir=/usr/local/var/mysql --tmpdir=/tmp
- but don't follow any more of the prompts just now or you will run into problems, we'll do the rest later.
- Execute the brew install process using hombrew-alt php brew file
$ brew tap josegonzalez/homebrew-php $ brew tap homebrew/dupes $ brew install php53 --with-mysql --with-fpm --with-imap $ brew install php53-xhprof $ brew install php53-xdebug $ brew install php53-uploadprogress
- Edit the php.ini
Search for the extenstions section by using CTRL + W and typing: extension=php_zip.dll (check the installed versions match the text below, and update accordingly)
$ nano /usr/local/etc/php/5.3/php.ini
extension="/usr/local/Cellar/php53-xhprof/0.9.2/xhprof.so" extension="/usr/local/Cellar/php53-uploadprogress/1.0.3.1/uploadprogress.so" zend_extension="/usr/local/Cellar/php53-xdebug/2.2.1/xdebug.so"
- Set your timezone http://www.php.net/manual/en/timezones.php, I added the follwing under the ;date.timezone = line
date.timezone = Australia/Melbourne
- Find and disable magic quotes, adding if not in php.ini already
magic_quotes_gpc = Off magic_quotes_runtime = Off magic_quotes_sybase = Off
- And updated the Memory limit as follows, then saved with Ctrl+X then Y
memory_limit = 256M
- Edit the php-fpm.conf file
$ nano /usr/local/etc/php/5.3/php-fpm.conf
- Add the following line below ;pid = run/php-fpm.pid
pid = /usr/local/var/run/php-fpm.pid
Remove the ; from the start of the following lines then save using Ctrl+X then Y - Make our log file visible in Console app
$ sudo ln -s $(brew --prefix josegonzalez/php/php53)/var/log/php-fpm.log /var/log/nginx/php-fpm.log
pm.start_servers = 3 pm.min_spare_servers = 3 pm.max_spare_servers = 5 pm.max_requests = 500
This is so everything runs automatically on startup
- Nginx needs to run as root for port 80 so do the following
$ sudo cp $(brew --prefix nginx)/homebrew.mxcl.nginx.plist /Library/LaunchDaemons/ $ sudo chown root:wheel /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
- Edit the plist
$ sudo nano /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
Remove the following 2 groups of text and save your changes using Ctrl+X then Y
<key>KeepAlive</key> <true/> <key>UserName</key> <string>yourusername</string>
Start nginx
$ launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.nginx.plist
- Make a directory for the rest of our launch daemons
$ mkdir -p ~/Library/LaunchAgents
- Copy the LaunchDaemon to load mariadb on boot into place and start it now
$ cp $(brew --prefix mariadb)/homebrew.mxcl.mariadb.plist ~/Library/LaunchAgents/ $ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mariadb.plist
- Copy php launch daemon and start it
$ cp $(brew --prefix josegonzalez/php/php53)/homebrew-php.josegonzalez.php53.plist ~/Library/LaunchAgents/ $ launchctl load -w ~/Library/LaunchAgents/homebrew-php.josegonzalez.php53.plist
- Complete the mariaDB setup
$ sudo $(brew --prefix mariadb)/bin/mysql_secure_installation
- Answer the prompts as follows, replace [password] with a password of your own chosing
Enter current password for root (enter for none): [Enter] Set root password? [Y/n] y New password: [password] Re-enter new password: [password] Remove anonymous users? [Y/n] y Disallow root login remotely? [Y/n] y Remove test database and access to it? [Y/n] y Reload privilege tables now? [Y/n] y
You're in the home stretch now!
- Install wget so Drush will work properly (need to do this on Mountain Lion)
$ brew install wget
- Make a few small changes required for this to work properly
$ sudo mkdir /var/aegir $ sudo chown `whoami` /var/aegir $ sudo chgrp staff /var/aegir $ sudo dscl . append /Groups/_www GroupMembership `whoami`
- Allow your user to restart nginx, be sure to replace [username] with your own username.
$ sudo -i $ echo "[username] ALL=NOPASSWD: /usr/local/bin/nginx" >> /etc/sudoers $ exit
- Create a symbolic link to aegir configuration
$ sudo ln -s /var/aegir/config/nginx.conf /usr/local/etc/nginx/aegir.conf
- To install aegir remember to replace client_email in the last command with your own email address
Remember to copy the one time login link and set your aegir admin password.$ brew install drush $ drush dl --destination=/users/`whoami`/.drush provision-6.x-2.x $ drush hostmaster-install --aegir_root='/var/aegir' --root='/var/aegir/hostmaster-6.x-2.x-dev' --http_service_type=nginx --aegir_host=aegir.ld --client_email=email@domain.com
- Remove the default platforms dir and create a symlink for so you can put your Platforms in ~/Sites/ directory
$ mkdir /Users/`whoami`/Sites $ rmdir /var/aegir/platforms $ ln -s /Users/`whoami`/Sites /var/aegir/platforms
- Disable the forced caching in aegir (this is for local dev after all!)
Paste the following text at the bottom of the document and save with CTRL +X then Y and return
$ nano /var/aegir/config/includes/global.inc
header('X-Accel-Expires: 0'); //disable nginx caching unset($conf['cache']); // disable hardcoded caching unset($conf['preprocess_css']); // disable hardcoded css aggregation unset($conf['preprocess_js']); // disable hardcoded js aggregation - Open your web browser and start creating platforms and sites!
http://aegir.ld






Comments
Thanks Brian! Excellent work.
Thanks Brian! Excellent work. I'm up and running now and it's working great. Currently running the same process over a few other machines in the office, so i'll let you know how we go on some newer machines!
thanks
I'm new to nginx, tried MNPP before, but MNPP is not compatible with 10.8. Tried to go through your howto. It seems to be everything ok, but I can not install phpmyadmin or set up an working nginx host. I would like to use it to local development (wordpress). Can you give me some tipps pls how to set up a host?
This blog post is
This blog post is specifically focused around using it for Drupal development, you can use different includes for your own manually created vhosts, take a look here for some info:
http://drupal.org/node/1044678
I've personally created a directory at:
/usr/local/etc/nginx/vhost.d
and my nginx.conf includes vhost files from that directory for any non drupal sites, but you will need to figure out the nginx rules that you require for them yourself.
Thanks Brian
All done! The only hiccup for me that wasn't mentioned in your post was that I needed to restart the machine before the local .ld domain was recognised.
Great Post
I found it also to work great. OS X 10.7.4
404 Not Found
Brian,
Awesome walkthrough, thanks for the write-up! I went through it and got pretty much everything working. I can log into Aegir and create platforms and sites. But whenever I go to visit the site after Aegir has created it, I get a 404 from nginx. Any idea what might be wrong? The Aegir backend works just fine.
Resolved itself
Oddly enough the problem resolved itself. Not quite sure what I did.
Where credit is due. http:/
Where credit is due. http://echodittolabs.org/blog/2012/04/os-x-107-lion-development-nginx-ph...
Trouble on 10.8.1
I was having all kinds of problems installing both MariaDB (specifically with Readline) and PHP threw Homebrew.
The solution was to add "--env=std" to their respective install commands.
mysql_install_db
Hi Brian,
Thanks a lot for this article. I'm trying to get through it but I'm stuck in the mariadb steps. I get the following when running mysql_install_db
$ mysql_install_db
FATAL ERROR: Could not find ./bin/my_print_default
Got past that bit
For anyone else with that problem, I had to run the
mysql_install_dbfrom following directory:/user/local/Cellar/mariadb/5.5.27I also had this problem and
I also had this problem and appreciated these comments as they helped me out. Thank you!
I had a little more complication so I thought I would share.
mysql_install_db wasn't found for me either. I found it in a slightly different directory then what Tim posted.
/usr/local/Cellar/mariadb/5.5.28/bin/mysql_install_db
I also had to sudo this. So my final command was:
sudo /usr/local/Cellar/mariadb/5.5.28/bin/mysql_install_db
*If you are still having trouble locating this file, try a search "find / -name "mysql_install_db"
You can also run "which mysql
You can also run "which mysql_install_db" to find it.
Problem with gzip --rsyncable
Drush 5.x uses Gzip with --rsyncable option which does not work with native Mountain Lion. In practise Hostmaster using Drush 5.x fails to backup sites, so also migrate fails as it is based on create-backup-generate-new-site-from-backup -workflow.
Solution is to install Macports from http://www.macports.org/install.php and upgrade gzip to newer version
$ gzip --version
gzip 1.3.12
Copyright (C) 2007 Free Software Foundation, Inc.
Copyright (C) 1993 Jean-loup Gailly.
This is free software. You may redistribute copies of it under the terms of
the GNU General Public License .
There is NO WARRANTY, to the extent permitted by law.
Written by Jean-loup Gailly.
$ sudo port
MacPorts 2.1.2
Entering interactive mode... ("help" for help, "quit" to quit)
> info gzip
gzip @1.5 (archivers)
Variants: universal
>install gzip
[for some 15 mins port will compiles gzip and required components]
>exit
Goodbye
Now exit terminal or reload bash configuration for change to take effect. Restarting nginx is probably also be necessary.
You should now have gzip version 1.5 as given in info gzip.
Use homebrew, one package manager is enough
Thanks Brian, would have
Thanks Brian, would have saved me some time if I had seen this a couple of weeks ago ;)
I also noticed that with (solution I described) editing $PATH in ~/.bash_profile was after all not enough, but after some pondering I realized cron had a different $PATH settings. I just switched /opt/local/bin as first item. Before that I just go bunch of tar write errors as a result of gzip failing with --rsyncable -parameter.
Still not working for me.
Still not working for me with gzip v. 1.5 that I picked up from homebrew.
Am about to try http://drupal.org/node/1901508
I uninstalled Macports and
I uninstalled Macports and thus their gzip. Tested with "regular" gzip through homebrew/dupes and it did not work. Version is the same, but flag --rsyncable does not exist. Patched one as per http://drupal.org/node/1901508 works fine.
Running OS X 10.8.x
My patch to the homebrew
My patch to the homebrew version of gzip is now included, so you don't need to apply it anymore